问题:我应该在Python字典上使用’has_key()’或’in’吗?
我不知道该怎么办:
d = {'a': 1, 'b': 2}
'a' in d
True
要么:
d = {'a': 1, 'b': 2}
d.has_key('a')
True
I wonder what is better to do:
d = {'a': 1, 'b': 2}
'a' in d
True
or:
d = {'a': 1, 'b': 2}
d.has_key('a')
True
回答 0
回答 1
in
不仅在优雅方面(而且不被弃用;-),而且在性能方面,都赢得了放手,例如:
$ 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中,更快的解决方案更加优雅和Pythonic。这就是为什么如此-mtimeit
有用的原因- 不仅仅是在这里和那里节省一百纳秒!-)
in
wins hands-down, not just in elegance (and not being deprecated;-) but also in performance, e.g.:
$ 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
While the following observation is not always true, you’ll notice that usually, in Python, the faster solution is more elegant and Pythonic; that’s why -mtimeit
is SO helpful — it’s not just about saving a hundred nanoseconds here and there!-)
回答 2
根据python docs:
has_key()
不推荐使用
key in d
。
According to python docs:
has_key()
is deprecated in favor of
key in d
.
回答 3
使用dict.has_key()
如果(且仅当)你的代码是要求Python版本早于2.3(当为可运key in dict
介绍)。
Use dict.has_key()
if (and only if) your code is required to be runnable by Python versions earlier than 2.3 (when key in dict
was introduced).
回答 4
有一个例子in
实际上会削弱您的表现。
如果你使用in
一个O(1)集装箱只实现__getitem__
和has_key()
而不是__contains__
你会变成一个O(1)搜索到O(N),搜索(如in
回落到通过线性搜索__getitem__
)。
修复显然是微不足道的:
def __contains__(self, x):
return self.has_key(x)
There is one example where in
actually kills your performance.
If you use in
on a O(1) container that only implements __getitem__
and has_key()
but not __contains__
you will turn an O(1) search into an O(N) search (as in
falls back to a linear search via __getitem__
).
Fix is obviously trivial:
def __contains__(self, x):
return self.has_key(x)
回答 5
has_key
是一个字典方法,但是in
可以在任何集合上使用,即使__contains__
丢失,in
也可以使用任何其他方法来迭代该集合以找出答案。
has_key
is a dictionary method, but in
will work on any collection, and even when __contains__
is missing, in
will use any other method to iterate the collection to find out.
回答 6
dict.has_key()的解决方案已弃用,请使用“ in”-sublime文本编辑器3
在这里,我举了一个名为“ age”的字典的例子-
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"
Solution to dict.has_key() is deprecated, use ‘in’ — sublime text editor 3
Here I have taken an example of dictionary named ‘ages’ –
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"
回答 7
亚当·帕金(Adam Parkin)的评论扩展了Alex Martelli的性能测试…
$ 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
Expanding on Alex Martelli’s performance tests with Adam Parkin’s comments…
$ 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
回答 8
如果您有这样的事情:
t.has_key(ew)
将其更改为以下版本以在Python 3.X及更高版本上运行:
key = ew
if key not in t
If you have something like this:
t.has_key(ew)
change it to below for running on Python 3.X and above:
key = ew
if key not in t