PT1*_*114 6 python dictionary conditional-operator
有没有办法在dict上执行三元运算,其中测试是has_key()而没有遇到键错误?即
variable = dict["the_key"] if dict.has_key("the_key") else "something"
Run Code Online (Sandbox Code Playgroud)
(这明显击中了关键错误)
如果没有这个,那么根据一个可能有也可能没有问题的字典来分配一堆变量值的最pythonic方法是什么?重复:
if dict.has_key('key'):
value = dict['key']
else:
value = "value"
Run Code Online (Sandbox Code Playgroud)
广告似乎非常不优雅.
Joc*_*zel 11
这个:
mydict.get(key, default_value)
Run Code Online (Sandbox Code Playgroud)
不是100%与default_value
直接评估的相同,而else
仅在满足条件时评估零件.
Jochen Ritzel的回答是在99.9999%的时间内做到这一点的正确方法:
variable = d.get("the key", "something")
Run Code Online (Sandbox Code Playgroud)
正如他所指出的,它不允许您短路评估默认值.你通常不在乎.它的默认值是"something"
,你当然不会.只有在生成默认值是危险的或非常昂贵的情况下才重要.
只有在这种情况下,您才能并且应该使用您的想法.除了你想要的in
而不是has_key
(因为它更可读,更快,而且不被弃用):
variable = d["the key"] if "the key" in d else expensiveComputation()
Run Code Online (Sandbox Code Playgroud)
但是,使用if
语句而不是三元表达式可能是值得的,因为您避免使用它的事实expensiveComputation
很重要,并且您希望它更加明显:
if "the_key" in d:
variable = d["the key"]
else:
variable = expensiveComputation()
Run Code Online (Sandbox Code Playgroud)
如果您希望默认情况很少见,那就更好了:
try:
variable = d["the key"]
except KeyError:
variable = expensiveComputation()
Run Code Online (Sandbox Code Playgroud)
如果由于某种原因你需要避免两次查找密钥,并且你也无法处理异常,并且你需要立即将默认值短路:
sentinel = object()
variable = d.get(sentinel)
if variable == sentinel:
variable = expensiveComputation()
Run Code Online (Sandbox Code Playgroud)
是的,你可以把它全部包含在一个函数中,所以它是一个单行,但你几乎肯定不想隐藏你一次做三件罕见事情的事实.
或者,当然,你可以这样做:
d = collections.defaultdict(expensiveComputation)
Run Code Online (Sandbox Code Playgroud)
然后,它只是:
variable = d["the key"]
Run Code Online (Sandbox Code Playgroud)
这具有在将其返回给您之前设置d["the key"]
为的副作用expensiveComputation()
,因此稍后调用d["the key"]
将返回相同的值.如果这听起来合适,这是最好的答案; 如果你永远不会两次使用相同的密钥,或者这些东西是巨大的,浪费,等等,这是一个坏主意.
或者,您也可以覆盖dict.__missing__
方法而不是使用defaultdict
:
class MyDict(dict):
def __missing__(self, key):
return expensiveComputation()
Run Code Online (Sandbox Code Playgroud)
然后,再次,它只是:
variable = d["the key"]
Run Code Online (Sandbox Code Playgroud)
当你想每次单独生成值时,这个适合,而不是为了以后保留它.