7

.items()我一直在尝试理解 Python 3 中由, .values(),.keys()或类似地由.viewitems(), .viewvalues(), .返回的内置视图对象.viewkeys()。关于该主题还有其他线程,但似乎没有一个(甚至doc )描述了它们在内部的工作方式。

与 Python 2 中返回的类型副本相比,这里的主要收获似乎是有效的list。经常将其比作字典项目的窗口(如在这个线程中)。

但是那个窗口是什么,为什么它更有效?

我唯一能看到的是视图对象似乎是 类似集合的对象,这对于成员资格测试通常更快。但这是唯一的因素吗?

代码示例

>>> example_dict = {'test':'test'}
>>> example_dict.items()
dict_items([('test', 'test')])
>>> type(example_dict.items())
<class 'dict_items'>

所以,我的问题是关于这dict_items门课的。这在内部如何运作?

4

2 回答 2

5

主要优点之一是视图是动态的:

>>> 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 2dict.items()视为 dict 的一种副本——就像复制时的样子。

将 Python 3dict.items()或 Python 2 等价物dict.viewitems()视为 dict 现在的最新副本。(显然与 .viewkeys()、.viewvalues() 相同。)

Python 3.6 文档有很好的例子说明为什么以及何时使用它。

值视图不像集合,因为 dicts 可以有重复的值。键视图是类似集合的,而项目视图对于具有可散列值的 dicts 是类似集合的。

注意:在 Python 3 中,视图替换了 Python 2 的内容,.keys() .values()或者.items()某些可能依赖dict.keys()dict.values()作为字典先前状态的静态表示可能会让人感到意外。

于 2017-11-13T20:53:36.240 回答
5

字典视图存储对其父字典的引用,并将视图上的操作转换为字典上的相应操作。

迭代 dict 视图比构建列表并对其进行迭代更有效,因为构建列表需要时间和内存,而您不必花费在视图上。旧的方式,Python 会遍历 dict 的底层存储来构建一个新的列表,然后你会遍历这个列表。迭代 dict 视图使用迭代器直接遍历 dict 的底层存储,跳过不必要的列表步骤。

Dict 视图还支持有效的包含测试和 setlike 交集/差异/等。操作,因为它们可以对底层 dict 执行直接哈希查找,而不是遍历列表并逐个元素检查相等性。

如果您想查看 CPython 使用的具体实现,可以查看官方存储库,但此实现可能会发生变化。它已经改变了,一再发生。

于 2017-11-13T21:00:13.653 回答