Mic*_*ber 25 python python-2.7
在Python 2.7中,字典既有iterkeys方法又有viewkeys方法(以及值和项的类似对),提供两种不同的方式来懒惰地迭代字典的键.该viewkeys方法提供的主要特征iterkeys,具有iter(d.viewkeys())实际上等效于d.iterkeys().此外,返回的对象viewkeys具有方便的类似集的功能.因此,有充分的理由看好viewkeys了iterkeys.
另一个方向呢?除了与早期版本的Python的兼容性之外,还有什么方法iterkeys比较好viewkeys?只要总是使用就会丢失任何东西viewkeys吗?
Gar*_*tty 21
字典视图会像字典一样更新,而迭代器不一定会这样做.
这意味着如果您使用视图,更改字典,然后再次使用视图,视图将更改以反映字典的新状态.
它们提供字典条目的动态视图,这意味着当字典更改时,视图会反映这些更改. 资源
例:
>>> test = {1: 2, 3: 4}
>>> a = test.iterkeys()
>>> b = test.viewkeys()
>>> del test[1]
>>> test[5] = 6
>>> list(a)
[3, 5]
>>> b
dict_keys([3, 5])
Run Code Online (Sandbox Code Playgroud)
对大小进行更改时,将引发异常:
>>> test = {1: 2, 3: 4}
>>> a = test.iterkeys()
>>> b = test.viewkeys()
>>> test[5] = 6
>>> list(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
>>> b
dict_keys([1, 3, 5])
Run Code Online (Sandbox Code Playgroud)
值得注意的是,您只能迭代一次keyiterator:
>>> test = {1: 2, 3: 4}
>>> a = test.iterkeys()
>>> list(a)
[1, 3]
>>> list(a)
[]
>>> b = test.viewkeys()
>>> b
dict_keys([1, 3])
>>> b
dict_keys([1, 3])
Run Code Online (Sandbox Code Playgroud)
Chr*_*gan 15
功能方面,正如您所观察到的,观点更好.兼容性方面,它们更糟糕.
一些性能指标,取自64位Ubuntu机器上的Python 2.7.2:
>>> from timeit import timeit
Run Code Online (Sandbox Code Playgroud)
处理空字典:
>>> emptydict = {}
>>> timeit(lambda: emptydict.viewkeys())
0.24384498596191406
>>> timeit(lambda: list(emptydict.viewkeys()))
0.4636681079864502
>>> timeit(lambda: emptydict.iterkeys())
0.23939013481140137
>>> timeit(lambda: list(emptydict.iterkeys()))
1.0098130702972412
Run Code Online (Sandbox Code Playgroud)
构造视图稍微昂贵一些,但是消耗视图的速度明显快于迭代器(速度快一倍).
处理千元字典:
>>> fulldict = {i: i for i in xrange(1000)}
>>> timeit(lambda: fulldict.viewkeys())
0.24295306205749512
>>> timeit(lambda: list(fulldict.viewkeys()))
13.447425842285156
>>> timeit(lambda: fulldict.iterkeys())
0.23759889602661133
>>> timeit(lambda: list(fulldict.iterkeys()))
15.45390510559082
Run Code Online (Sandbox Code Playgroud)
结果相同,但不太明显; 构建视图的成本略高,但消耗它的速度肯定更快(快15%).
对于公平的比较list(dict.viewkeys())和list(dict.iterkeys()),dict.keys()是distinctlyfaster:
>>> timeit(lambda: emptydict.keys())
0.2385849952697754
>>> timeit(lambda: fulldict.keys())
7.842105150222778
Run Code Online (Sandbox Code Playgroud)
总结:这是一种权衡; 更好的功能(你将很少使用)和性能(这只会非常罕见足以显著担心你,如果你关心这样的表现的问题,你可能已经在需要的区域与numpy的/ SciPy的工作)与更好的兼容性和肌肉记忆使用.
就个人而言,除非已经依赖于2.7-only功能,或者除非我绝对控制运行时环境,否则我会避免使用Python 2代码中的字典视图.即使在这些情况下,我的手指仍然想要打字iter而不是view,所以我让他们!
lvc*_*lvc 11
不,没有任何优势可以iterkeys结束viewkeys,就像它们中的任何一个都没有优势keys一样.iterkeys只是为了兼容后兼容.实际上,在Python 3中,viewkeys唯一仍然存在的行为,并且它已被重命名为keys- 该viewkeys方法实际上是Python 3行为的后端.
正如其名字(和文档)所表明,viewkeys(),viewvalues()和viewitems()方法都返回一个视图在字典中的意思,如果词典的变化,因此不认为当前元件; 意见很 懒散.在一般情况下,键视图是类似于集合的,并且如果值是可哈希的,则项目视图仅设置为类似.
在什么情况下使用标准方法会更好keys(),values()并且items()?你提到了一个非常重要的问题:向后兼容性.此外,当您需要拥有所有键,值或项(不是类似集合,而不是迭代器)的简单列表时,需要在不修改原始字典的情况下修改返回的列表以及何时需要快照字典的键,值或项目在某个时刻,独立于字典上的任何后验修改.
又是怎么回事iterkeys(),itervalues()和iteritems()?当你需要一个字典内容的一次性,恒定空间,懒惰的迭代器快照时,它们是一个合适的选择,它会告诉你字典是否在迭代时被修改(通过a RuntimeError),它们对于向后兼容性非常重要.
| 归档时间: |
|
| 查看次数: |
38839 次 |
| 最近记录: |