Python 2.7与3.4上的字典查找 - python

如果您需要对值进行一些测试,那么这是在nitpick讨论中提出的,该讨论讨论了对字典键进行迭代的首选样式。我正在比较[k for k in d if d[k] == 1][k for k, v in d.items() if v == 1]的性能。

看起来字典查询在Python 3.4中更昂贵:

$ python -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k in d if d[k] == 1]'
1000000 loops, best of 3: 2.17 usec per loop

$ python -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k, v in d.items() if v == 1]'
1000000 loops, best of 3: 3.13 usec per loop

$ python3.4 -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k in d if d[k] == 1]'
1000000 loops, best of 3: 3.25 usec per loop

$ python3.4 -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k, v in d.items() if v == 1]'
1000000 loops, best of 3: 3.05 usec per loop

与2.7相比,Python 3.4中的查找昂贵吗?您能解释为什么吗?

python大神给出的解决方案

不是说Python 3.4中的查找比2.7中的查找更昂贵,而是dict.items()便宜。这是因为dict.items()在两种语言版本中是完全不同的野兽:

$ python2.7
Python 2.7.9 (default, Dec 11 2014, 03:19:35) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> type({}.items())
<type 'list'>
>>> 
$ python3.4
Python 3.4.2 (default, Oct  8 2014, 08:07:42) 
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> type({}.items())
<class 'dict_items'>
>>> 

在Python 2中,dict.items()构造并返回一个列表,而在Python 3中,它返回一个dictionary view,事实证明,将此动态视图迭代到字典中比构建一个列表然后对其进行迭代要快。

尽管dict.items()在2.7中不返回字典视图,但可以使用dict.viewitems()获得一个视图,具有类似的性能优势。重复测试,这次包括viewitems(),我得到:

$ python2.7 -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k in d if d[k] == 1]'
1000000 loops, best of 3: 3.38 usec per loop
$ python2.7 -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k, v in d.items() if v == 1]'
1000000 loops, best of 3: 4.33 usec per loop
$ python2.7 -m timeit -n 1000000 \
  -s 'd={k:v for v, k in enumerate("abcdefghijhklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")}' \
  '[k for k, v in d.viewitems() if v == 1]'
1000000 loops, best of 3: 3.27 usec per loop

关于促使您进行调查的讨论,我想说d.items()d.viewitems()方法更明确,因此更Python化,但这实际上是比其他任何事物都更美观的选择。

1除非Python 3.x通常比2.x慢,但这是进步的代价...