字典上的三元操作

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仅在满足条件时评估零件.


aba*_*ert 8

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)

当你想每次单独生成值时,这个适合,而不是为了以后保留它.