'has_key()'或'in'?

我不知道什么是更好的做法:

d = {'a': 1, 'b': 2} 'a' in d True 

要么:

 d = {'a': 1, 'b': 2} d.has_key('a') True 

in肯定更pythonic。

实际上, has_key()在Python 3.x中被删除了 。

不仅在优雅(而不是被弃用;-)而且在performance方面也是如此:

 $ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d' 10000000 loops, best of 3: 0.0983 usec per loop $ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)' 1000000 loops, best of 3: 0.21 usec per loop 

虽然下面的观察并不总是正确的,但是你会注意到, 通常在Python中,更快的解决scheme更加优雅,而Pythonic也是如此。 这就是为什么-mtimeit是如此有用 – 这不仅仅是在这里和那里节省了一百纳秒 – )

根据python 文档 :

has_key()被弃用,以支持key in dkey in d

使用dict.has_key() if(且仅当)您的代码需要可以在Python 2.3以前版本(引入key in dict时)运行。

有一个例子, in实际上杀死你的performance。

如果您in仅使用__getitem__has_key()而不是__contains__的O(1)容器中使用,则会将O(1)search转换为O(N)search(如通过__getitem__退回到线性search) 。

修复显然是微不足道的:

 def __contains__(self, x): return self.has_key(x) 

has_key是一个字典方法,但是in任何集合in都可以工作,即使在__contains__缺失的情况下,也会使用其他方法迭代集合来查找。

Python 2.x支持has_key()

Python 2.3+和Python 3.x支持。

dict.has_key()的解决方法已被废弃,请使用'in' – 崇高文本编辑器3

这里我举了一个名为“年龄”的字典的例子 –

 ages = {} # Add a couple of names to the dictionary ages['Sue'] = 23 ages['Peter'] = 19 ages['Andrew'] = 78 ages['Karren'] = 45 # use of 'in' in if condition instead of function_name.has_key(key-name). if 'Sue' in ages: print "Sue is in the dictionary. She is", ages['Sue'], "years old" else: print "Sue is not in the dictionary" 

如果您的意图是使用默认值,以防钥匙不在字典中

 my_dict.get('key') or default_value 

是一种跳过检查的方式。 如果密钥不在字典中,则返回None 。 与使用in一样,速度也是O(1)。

你也可以使用

 my_dict.get('key', default_value) 

但是我发现可读性较差。

Adam Parkin的评论扩展了Alex Martelli的性能testing

 $ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)' Traceback (most recent call last): File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 301, in main x = t.timeit(number) File "/usr/local/Cellar/python3/3.5.2_3/Frameworks/Python.framework/Versions/3.5/lib/python3.5/timeit.py", line 178, in timeit timing = self.inner(it, self.timer) File "<timeit-src>", line 6, in inner d.has_key(12) AttributeError: 'dict' object has no attribute 'has_key' $ python2.7 -mtimeit -s'd=dict.fromkeys(range( 99))' 'd.has_key(12)' 10000000 loops, best of 3: 0.0872 usec per loop $ python2.7 -mtimeit -s'd=dict.fromkeys(range(1999))' 'd.has_key(12)' 10000000 loops, best of 3: 0.0858 usec per loop $ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d' 10000000 loops, best of 3: 0.031 usec per loop $ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d' 10000000 loops, best of 3: 0.033 usec per loop $ python3.5 -mtimeit -s'd=dict.fromkeys(range( 99))' '12 in d.keys()' 10000000 loops, best of 3: 0.115 usec per loop $ python3.5 -mtimeit -s'd=dict.fromkeys(range(1999))' '12 in d.keys()' 10000000 loops, best of 3: 0.117 usec per loop 

如果你有这样的事情

 t.has_key(ew) 

将其更改为在Python 3.X及更高版本上运行

 key = ew if key not in t 

该API看起来是这样做的一个原因…使用内置types的API作为logging是Pythonic …

您通常应该执行my_dict.get('key', default_value)而不是my_dict.get('key') or default_value

奇怪的情况是希望用default_value my_dictmy_dict返回的所有假等价值( 0''[]等)。

实际上,如果打算从字典中获取默认值,为什么不使用collections.defaultdict而不是内置dict呢?

 >>> from collections import defaultdict >>> d42 = defaultdict(lambda: 42) >>> d42['x'] = 18 >>> d42['x'] 18 >>> d42['y'] 42 

defaultdicts最常见的用例可能是列表types,例如:

 >>> dl = defaultdict(list) >>> for x, y in some_list_of_tuples: ... dl[x].append(y) >>>