Python:了解字典视图对象

Python: Understanding dictionary view objects

我一直在尝试通过 .items().values().keys() 3 中的 return 或类似的方式来理解内置视图对象 return .viewitems().viewvalues().viewkeys()。关于该主题还有其他主题,但 none(甚至 doc)似乎描述了它们的内部工作方式。

与 Python 中 list return 类型的副本相比,这里的主要收获似乎是高效的 2. 通常与 window 到字典项(如 thread)。

但那是什么 window 为什么它更有效?

我唯一能看到的是视图对象似乎是 set-like 对象,这对于成员测试通常更快。但这是唯一的因素吗?

代码示例

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

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

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

>>> 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() 视为字典的一种副本 - 制作副本时的方式。

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

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

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

注意:使用 Python 3,视图将 Python 2 替换为 .keys() .values().items() 有些人可能依赖于 dict.keys()dict.values() 作为字典先前状态的静态表示可能会有惊喜。

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

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

Dict 视图还支持高效的包含测试和 setlike intersection/difference/etc。操作,因为它们可以在底层 dict 上执行直接散列查找,而不是遍历列表并逐个元素检查相等性。

如果你想看CPython使用的具体实现,你可以去official repository看看,但是这个实现可能会有变化。它已经改变,反复。