python 视图对象_Python:了解字典视图对象

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

与Python 2中返回的类型list的副本相比,这里的主要收益似乎是有效的。通常将其与字典项的窗口进行比较(例如在此线程中)。

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

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

代码样例

>>> example_dict = {'test':'test'}

>>> example_dict.items()

dict_items([('test', 'test')])

>>> type(example_dict.items())

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

您是否阅读过:stackoverflow.com/questions/8957750/

我确实读过它,但是正如我在问题中所说的那样,它使用了窗口类比,而我无法深入了解Python内部部分。

@vaultah我真的不认为这是重复的,因为它没有描述他的窗口代表了我所要询问的内容。如果您仍然认为是,您能解释一下什么是魔术窗口吗?

投票结果最高的答案的最后一段说:"总而言之,视图就是…词典中的视图(窗口),即使词典发生更改,视图仍会显示它们的内容"。这不能回答您的问题吗?

@vaultah:"窗口"确实模糊且模糊。它实际上并没有比"视图"更好,并且"视图"一词也没有说明问题。从一个已经了解该主题的人的角度来看,它的解释并不像看起来那样好。

就像我说的,视图只是…词典中的视图(窗口),这些窗口是什么?一个列表 ?一套 ?词典?参考?也许我的问题是一个完全重复的问题,如果这是第一个承认的问题,但我真的不明白所接受答案中的窗口内容。

@ user2357112我同意,这正是我要强调的内容,我在问题中添加了链接,这样人们就不会对为什么我问这个感到困惑。

@ user2357112好,您也没有解释"窗口"术语吗?据我所知,您的答案与链接页面上的答案没有太大不同。您为什么感到被迫重新打开问题以发布答案(即处于当前状态)?毕竟,您可以在此处发布它。

@vaultah:我的回答解释了视图的实际作用。它不使用"窗口"一词,因为我认为该词不会帮助解释视图的实际作用。

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

>>> 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()或等效于dict.viewitems()的Python 2视为dict的最新副本。 (显然与.viewkeys()、. viewvalues()相同。)

Python 3.6文档提供了一个很好的示例,说明了为什么以及何时使用它。

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

注意:使用Python 3时,视图用.keys() .values()或.items()替换了Python 2的视图。有些人可能依赖dict.keys()或dict.values()是字典先前状态的静态表示,这可能会令人惊讶。

"因此,如果字典发生更改,则无需重新生成项目,键或值列表"-但标准用法仍然是每次使用一个视图时都会创建一个新视图,因为创建视图很便宜。很少有人看到一个人来存放它。

@ user2357112:"很少有人会费心地存储一个视图"。如果查看文档,示例将显示按名称存储视图。您是否有一个示例,它比引用命名对象要好一些?

实际上,字典视图的大多数用法是for key, val in d.items()或for v in d.values()之类的东西。我从未见过有人为保存视图的引用而烦恼。

抓取一些任意的Github存储库(Django,Scikit-learn和CPython)并在其中搜索关键字items,我唯一看到有人存储dict视图的地方就是dict视图测试用例。

但是,如果您不命名视图,则视图的动态性质就不那么明显了。当您使用for k, v in d.viewitems()之类的视图遍历视图时,同时更改dict的情况很少。您能举例说明那是真的吗?

有时,人们希望在迭代字典时更改键的值。在这种情况下,它仍然不是真正可见的,因为它通常会更改当前键的值,而不是其他键的值,并且迭代器不会重新获取当前键的值。

我将再次参考Python 3 dict.items()上的文档:在字典中添加或删除条目时迭代视图可能会引发RuntimeError或无法迭代所有条目。您只能更改现有键的值,但是为什么要使该特定情况动态?我认为这只是Python 2中使用dict.iteritems()的更优雅的演变。

谢谢您的见识!

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

在dict视图上进行迭代比在列表上进行迭代更有效,因为构建列表需要花费时间和内存,而您不必在视图上花费时间。旧的方法是,Python将遍历dict的基础存储以构建新列表,然后遍历该列表。 dict视图为您提供了一个迭代器,该迭代器直接遍历dict的基础存储,而跳过了不必要的列表步骤。

字典视图还支持有效的封闭性测试以及类似交集/差异/等。操作,因为它们可以对基础dict进行直接哈希查找,而不是遍历列表并逐元素检查相等性。

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

我喜欢这个答案。只是一个语言上的小问题:" ...它们将视图上的操作转换为字典上的相应操作。"这表明您可以通过一个不正确的视图对字典进行更改,不是吗?

不想脱离上下文,但是Dict视图是什么意思存储对其父dict的引用?

@scharette:想象一下dict视图由self._secret_inaccessible_attribute = the_dict_youre_making_a_view_of组成。就是这样,但是在C中。

这正是我一直在寻找的答案。谢谢 !

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值