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看看,但是这个实现可能会有变化。它已经改变,反复。
我一直在尝试通过 .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看看,但是这个实现可能会有变化。它已经改变,反复。