我一直试图了解内置视图对象在Python 3中的.items()
,.values()
,.keys()
或.viewitems()
,{{ 1}},.viewvalues()
。该主题还有其他主题,但没有一个(甚至doc)似乎描述了它们如何在内部工作。
与Python 2中返回的类型.viewkeys()
的副本相比,这里的主要增益似乎是有效的。通常将 窗口 与字典项目(如此thread)。
但 窗口 是什么?为什么效率更高?
我唯一能看到的是视图对象似乎是类似于的对象,对于成员资格测试来说通常更快。但这是唯一的因素吗?
代码示例
list
所以,我的问题是关于这个>>> example_dict = {'test':'test'}
>>> example_dict.items()
dict_items([('test', 'test')])
>>> type(example_dict.items())
<class 'dict_items'>
课程。这在内部如何运作?
答案 0 :(得分:2)
其中一个主要优点是观点是动态的:
>>> di={1:'one',2:'two',3:'three'}
>>> view=di.viewitems()
>>> view
dict_items([(1, 'one'), (2, 'two'), (3, 'three')])
>>> di[2]='new two'
>>> view
dict_items([(1, 'one'), (2, 'new two'), (3, 'three')])
因此,如果字典更改,则无需重新生成项目,键或值列表(就像使用dict.items()
一样)。
将Python 2 dict.items()
视为dict副本的一种类型 - 复制时的方式。
将Python 3 dict.items()
或Python 2等效于dict.viewitems()
视为dict现在的最新版本。 (显然与.viewkeys(),。viewvalues()相同。)
Python 3.6 documents有很好的例子说明为什么以及何时使用它。
值视图没有设置,因为dicts可以有重复的值。关键视图是类似于集合的,并且项目视图与具有可散列值的dicts类似。
注意:在Python 3中,视图取代了Python 2与.keys()
.values()
或.items()
的相关内容。有些人可能依赖于dict.keys()
或dict.values()
字典的先前状态的静态表示可能会令人惊讶。
答案 1 :(得分:1)
Dict视图存储对其父dict的引用,并将视图上的操作转换为dict上的相应操作。
对dict视图的迭代比构建列表并迭代它更有效,因为构建列表需要花费时间和内存,而不必花费在视图上。旧的方式,Python将迭代dict的底层存储来构建一个新的列表,然后你将迭代列表。 dict视图为您提供了一个迭代器,它直接遍历dict的底层存储,跳过不必要的列表步骤。
Dict视图还支持有效的包含测试和setlike intersection / difference / etc.操作,因为他们可以在底层字典上执行直接哈希查找,而不是遍历列表并逐个元素地检查相等。
如果您想查看CPython使用的具体实现,可以查看official repository,但此实现可能会有所变化。它反复改变了。