python中的字典理解太全面了

德米特里(Dmitrii Borisevich)

使用python2.7我发现了一个奇怪的时间执行案例:

data = dict( zip( a[0].split( ':' ), a[1].split( ':' ) ) )

data = { name: value for name, value in zip(a[0].split( ':' ), a[1].split( ':' )) }

这两个调用对我来说似乎绝对相同,但是,我发现字典理解版本的速度提高了约4%-不太快,但是非常稳定。

这是真的吗?如果是这样,为什么?还是仅仅是我的想象力?

马丁·彼得斯(Martijn Pieters)

您的输入样本太小。查找全局名称dict()比仅运行dict理解需要更多的时间(后者不需要名称查找),但是如果您对大量键值对进行测试,则dict()因为完全在C中完成了循环。

针对大量键/值对测试差异,并将测试简化为仅dict()调用或字典理解(zip()str.split()调用对于两种情况仅执行一次,可以忽略):

>>> from timeit import timeit
>>> import random
>>> from string import ascii_lowercase
>>> kv_pairs = [(''.join(random.sample(ascii_lowercase, random.randint(10, 20))), ''.join(random.sample(ascii_lowercase, random.randint(10, 20))))
...             for _ in xrange(10000)]
>>> len(dict(kv_pairs))  # the random keys happen to be all unique.
10000
>>> timeit('{k: v for k, v in kv_pairs}', 'from __main__ import kv_pairs', number=1000)
1.3174479007720947
>>> timeit('dict(kv_pairs)', 'from __main__ import kv_pairs', number=1000)
0.6737580299377441
>>> timeit('{k: v for k, v in kv_pairs}', 'from __main__ import kv_pairs; kv_pairs = kv_pairs[:3]')
0.511167049407959
>>> timeit('dict(kv_pairs)', 'from __main__ import kv_pairs; kv_pairs = kv_pairs[:3]')
0.6696300506591797

因此,对于1万个键/值对(前两个时序测试)而言,dict()速度快一倍,对于3对(后两个时序)而言,dict理解力胜了。

您可以看到为什么反编译字节码的原因;字典理解使用嵌套的代码对象来实现实际的字典构建:

>>> import dis
>>> dis.dis(compile('{k: v for k, v in kv_pairs}', '', 'exec'))
  1           0 LOAD_CONST               0 (<code object <dictcomp> at 0x102ef69b0, file "", line 1>)
              3 MAKE_FUNCTION            0
              6 LOAD_NAME                0 (kv_pairs)
              9 GET_ITER            
             10 CALL_FUNCTION            1
             13 POP_TOP             
             14 LOAD_CONST               1 (None)
             17 RETURN_VALUE        
>>> dis.dis(compile('{k: v for k, v in kv_pairs}', '', 'exec').co_consts[0])
  1           0 BUILD_MAP                0
              3 LOAD_FAST                0 (.0)
        >>    6 FOR_ITER                21 (to 30)
              9 UNPACK_SEQUENCE          2
             12 STORE_FAST               1 (k)
             15 STORE_FAST               2 (v)
             18 LOAD_FAST                2 (v)
             21 LOAD_FAST                1 (k)
             24 MAP_ADD                  2
             27 JUMP_ABSOLUTE            6
        >>   30 RETURN_VALUE        
>>> dis.dis(compile('dict(kv_pairs)', '', 'exec'))
  1           0 LOAD_NAME                0 (dict)
              3 LOAD_NAME                1 (kv_pairs)
              6 CALL_FUNCTION            1
              9 POP_TOP             
             10 LOAD_CONST               0 (None)
             13 RETURN_VALUE        

通过使用一个非常小的样本,您为LOAD_NAME步骤付出了dict太多的重量。dict理解涉及更多​​的字节码,每次迭代执行一次。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

嵌套字典理解python

来自分类Dev

如何以正确的顺序在Python中构造嵌套字典理解?

来自分类Dev

Python 3中的字典理解

来自分类Dev

IO Monad的flatMap和全面理解

来自分类Dev

字典的Python列表理解示例

来自分类Dev

使用理解来创建Python字典

来自分类Dev

使用locals()的Python字典理解给出KeyError

来自分类Dev

在python中,“ if-else and for”如何在字典理解中工作

来自分类Dev

嵌套的Python字典理解

来自分类Dev

python中具有理解力的字典列表

来自分类Dev

Python-OrderedDict中的字典理解不起作用

来自分类Dev

python中的字典理解太全面

来自分类Dev

字典的python理解循环

来自分类Dev

使用math.isclose比较python中的字典,如何在字典理解中实现

来自分类Dev

带有值列表的Python中的嵌套字典理解

来自分类Dev

Python中的字典理解

来自分类Dev

cats.data.WriterT的全面理解中忽略的参数

来自分类Dev

Python列表和字典理解

来自分类Dev

Python3字典理解

来自分类Dev

在Python的列表/字典理解中的每个元素中创建单独的实例

来自分类Dev

IO Monad的flatMap和全面理解

来自分类Dev

如何以正确的顺序在Python中构造嵌套字典理解?

来自分类Dev

字典中的Python列表理解

来自分类Dev

列出为字典理解中每个键的值-Python

来自分类Dev

python列表理解按键获取字典

来自分类Dev

在Python中通过列表全面搜索访问对象

来自分类Dev

字典理解中的 if-else

来自分类Dev

在字典理解中循环

来自分类Dev

字典中的频率计数——Python 使用理解