Python 什么是字典视图对象?
在Python2.7中,我们得到了可用的 现在,我知道以下的利弊:Python 什么是字典视图对象?,python,view,dictionary,Python,View,Dictionary,在Python2.7中,我们得到了可用的 现在,我知道以下的利弊: dict.items()(和值,键):返回一个列表,以便实际存储结果,然后 dict.iteritems()(及类似内容):返回一个生成器,因此您可以逐个迭代生成的每个值 dict.viewitems()(及类似内容)的用途是什么?它们的好处是什么?它是如何工作的?究竟什么是景观 我读到,这种观点总是反映出字典中的变化。但是从性能和内存的角度来看,它是如何工作的呢?优缺点是什么?视图方法返回一个列表(与.keys()、.it
(和dict.items()
,值
):返回一个列表,以便实际存储结果,然后键
(及类似内容):返回一个生成器,因此您可以逐个迭代生成的每个值李>dict.iteritems()
dict.viewitems()
(及类似内容)的用途是什么?它们的好处是什么?它是如何工作的?究竟什么是景观
我读到,这种观点总是反映出字典中的变化。但是从性能和内存的角度来看,它是如何工作的呢?优缺点是什么?视图方法返回一个列表(与
.keys()
、.items()
和.values()
相比,它不是列表的副本),因此它更轻量级,但反映了字典的当前内容
从
主要原因是,对于许多用例,返回一个完整的
分离列表是不必要和浪费的。这需要复制
整个内容(可能很多,也可能不是很多)
如果您只是想迭代这些键,那么创建一个新列表
没有必要。如果您确实需要它作为一个单独的列表(作为
复制)然后可以从视图轻松创建该列表
仅仅通过阅读文档,我就得到了这样的印象:
所以我想关键的用例是,如果你保持一个字典,并反复迭代它的键/项/值,其间进行修改。您可以只使用视图,将mydict.iteritems()中k,v的
转换为myview中k,v的:
。但是如果你只是在字典上迭代一次,我认为iter版本还是比较好的。字典视图基本上就是它们的名字所说的:视图就像字典键和值(或项)上的一个窗口。以下是Python3版本的摘录:
>>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
>>> keys = dishes.keys()
>>> values = dishes.values()
>>> # view objects are dynamic and reflect dict changes
>>> del dishes['eggs']
>>> keys # No eggs anymore!
dict_keys(['sausage', 'bacon', 'spam'])
>>> values # No eggs value (2) anymore!
dict_values([1, 1, 500])
(Python2等价物使用disks.viewkeys()
和disks.viewvalues()
)
此示例显示视图的动态特性:关键点视图不是给定时间点关键点的副本,而是显示关键点的简单窗口;如果它们被改变了,那么你通过窗口看到的也会改变。此功能在某些情况下非常有用(例如,可以使用程序多个部分中键的视图,而不是每次需要时重新计算当前键列表)-请注意,如果在视图上迭代时修改了字典键,则迭代器的行为未得到很好的定义,哪个可以
一个优点是,例如,查看键只使用小而固定的内存量,并且需要小而固定的处理器时间,因为不需要创建键列表(另一方面,Python2经常不必要地创建一个新列表,正如Rajendran T所引用的那样,它占用的内存和时间与列表的长度成正比)。要继续窗口类比,如果你想看到墙后的风景,你只需在其中开一个口(你构建了一个窗口);将关键点复制到列表中相当于在墙上绘制风景的副本。副本需要时间、空间,并且不会自动更新
总而言之,视图只是…视图(窗口)在您的字典上,即使字典发生更改,也会显示其内容。它们提供了与列表不同的功能:键列表包含给定时间点的字典键副本,而视图是动态的,获取速度更快,因为它不必复制任何数据(键或值)为了被创建。正如您提到的dict.items()
返回字典的(键,值)对列表的副本,这是浪费的,dict.iteritems()
返回字典的(键,值)对的迭代器
现在以下面的例子来看dict的interator和dict视图之间的区别
>>> d = {"x":5, "y":3}
>>> iter = d.iteritems()
>>> del d["x"]
>>> for i in iter: print i
...
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration
视图只是字典现在的样子。删除条目后,.items()
将过期,.iteritems()
会引发错误。视图允许您访问参考底图数据结构,而无需复制它。除了作为动态视图而不是创建列表外,它们最有用的用法之一是在测试中使用。假设您想检查dict中是否有值(它是键还是值)
选项一是使用dict.keys()
创建一个密钥列表,这样做有效,但显然会消耗更多内存。如果dict非常大,那将是浪费
使用视图
可以迭代实际的数据结构,而无需中间列表
让我们举个例子,我有一个包含1000个随机字符串和数字的dict
>>> d = {"x":5, "y":3}
>>> v = d.viewitems()
>>> v
dict_items([('y', 3), ('x', 5)])
>>> del d["x"]
>>> v
dict_items([('y', 3)])
large_d = { .. 'NBBDC': '0RMLH', 'E01AS': 'UAZIQ', 'G0SSL': '6117Y', 'LYBZ7': 'VC8JQ' .. }
>>> len(large_d)
1000
# this is one option; It creates the keys() list every time, it's here just for the example
timeit.timeit('k in large_d.keys()', setup='from __main__ import large_d, k', number=1000000)
13.748743600954867
# now let's create the list first; only then check for containment
>>> list_keys = large_d.keys()
>>> timeit.timeit('k in list_keys', setup='from __main__ import large_d, k, list_keys', number=1000000)
8.874809793833492
# this saves us ~5 seconds. Great!
# let's try the views now
>>> timeit.timeit('k in large_d.viewkeys()', setup='from __main__ import large_d, k', number=1000000)
0.08828549011070663
# How about saving another 8.5 seconds?