当前位置:  开发笔记 > 编程语言 > 正文

Python 3.0 - dict方法返回视图 - 为什么?

如何解决《Python3.0-dict方法返回视图-为什么?》经验,为你挑选了2个好方法。

你实际上得到了一个清单.它不是内部列表的副本,而是表现为列表但仅代表内部状态的内容.

这与它在Java中实现的方式相同(也可能是许多其他语言/环境).

主要原因是,对于许多用例而言,返回完全独立的列表是不必要和浪费的.它需要复制整个内容(可能或许多不是很多).

如果您只想迭代密钥,则无需创建新列表.如果您确实需要它作为单独的列表(作为副本),那么您可以从视图中轻松创建该列表.



1> Joachim Saue..:

你实际上得到了一个清单.它不是内部列表的副本,而是表现为列表但仅代表内部状态的内容.

这与它在Java中实现的方式相同(也可能是许多其他语言/环境).

主要原因是,对于许多用例而言,返回完全独立的列表是不必要和浪费的.它需要复制整个内容(可能或许多不是很多).

如果您只想迭代密钥,则无需创建新列表.如果您确实需要它作为单独的列表(作为副本),那么您可以从视图中轻松创建该列表.



2> max..:

Joachim Sauer的回答很好地解释了为什么a list不归还.但这就留下了一个问题,为什么这些函数不会返回迭代器,就像iteritems在Python 2中那样.

迭代器比容器更具限制性.例如,迭代器不允许多次传递; 如果你尝试第二次传球,你会发现它是空的.因此,诸如elem in cont容器支持的操作,但迭代器不能支持:一旦检查元素是否在迭代器中,迭代器就会被破坏!

另一方面,获取容器通常需要制作副本,例如从字典的键中创建列表.

view对象具有两全其美的优点:它表现为容器,但不会复制字典!事实上,它是一种虚拟只读容器,通过链接到底层字典来工作.我不知道它是否在标准Python的其他地方出现过.

编辑:

@AntonyHatchkins:它不返回生成器函数的原因是它不允许快速in操作.是的,in适用于生成器功能(当您调用它们时).也就是说,你可以这样做:

def f():
  for i in range(10):
    yield i

5 in f() # True

但根据定义in,如果右侧是生成器,python将遍历n生成器的所有项目 - 导致O(n)时间复杂性.你无能为力,因为这是任意发电机唯一有意义的行为.

另一方面,对于字典视图,您可以in按照自己喜欢的方式实现,因为您对所管理的数据有了更多了解.事实上in,O(1)使用哈希表实现了复杂性.你可以通过运行来检查它

>>> d = dict(zip(range(50000000), range(50000000)))
>>> 49999999 in d
True
>>> 49999999 in iter(d) # kinda how generator function would work
True
>>>

并注意到第一个in与第二个相比有多快in.

推荐阅读
coco2冰冰
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有