0

在 Python 中,我经常使用以下构造:

x = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
y = x[v] if v in x.keys() else None

其中 v 通常是字典值之一,如果键存在,则 y 获取字典的值,否则为无。

我想知道这是否是一种理想的构造,或者是否可以增强?

x[v] 可以是上述值,但我也使用类似的构造来根据 v 的值调用函数,例如:

{'a': self.f1, 'b': self.f2, 'c': self.f3, 'd': self.f4}[v]()
4

3 回答 3

6

通常你会使用dict.get()

y = x.get(v)

.get()v如果字典中不存在,则采用默认参数返回,但如果您省略它,None则返回。

即使您要使用显式密钥测试,也不需要使用.keys()

y = x[v] if v in x else None

有趣的是,条件表达式选项稍微快一些:

>>> [x.get(v) for v in 'acxz']  # demonstration of the test; two hits, two misses
[1, 3, None, None]
>>> timeit.timeit("for v in 'acxz': x.get(v)", 'from __main__ import x')
0.8269917964935303
>>> timeit.timeit("for v in 'acxz': x[v] if v in x else None", 'from __main__ import x')
0.67330002784729

直到您避免属性查找.get()

>>> timeit.timeit("for v in 'acxz': get(v)", 'from __main__ import x; get = x.get')
0.6585619449615479

因此,如果速度很重要,请存储对该.get()方法的引用(注意get = x.get分配)。

于 2013-05-30T15:04:48.857 回答
2

你所描述的可以这样说:

“如果字典中存在“v”,则y应该是键“v”的值,否则它应该是“none”

在 Python 中,即:

y = x.get(v, None)

注意: None当key不存在时已经是默认返回值了。


在您的问题中,您还提到有时您的字典包含对方法的引用。在这种情况下,y如果不是,则将是该方法None,您可以正常调用它:

y(*args, **kwargs)

或者像你的例子一样:

{'a': self.f1, 'b': self.f2, 'c': self.f3, 'd': self.f4}.get(v)()

注意:如果键不在字典中,那么它将引发TypeError

于 2013-05-30T15:05:56.500 回答
1

在花了很多时间分析一些类似的代码之后,我发现最有效的方法是使用defaultdict......

from collections import defaultdict

x = defaultdict(lambda: None, {'a': 1, 'b': 2, 'c': 3, 'd': 4})
y = x[v]

...其次最有效的是两个关键查找...

x = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
y = x[v] if x in v else None

这两个都比这快得多......

x = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
y = x.get(v, None)

...和这个...

x = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
try:
    y = x[v]
except KeyError:
    y = None
于 2013-05-30T15:15:27.827 回答