Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/327.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 什么是字典视图对象?_Python_View_Dictionary - Fatal编程技术网

Python 什么是字典视图对象?

Python 什么是字典视图对象?,python,view,dictionary,Python,View,Dictionary,在Python2.7中,我们得到了可用的 现在,我知道以下的利弊: dict.items()(和值,键):返回一个列表,以便实际存储结果,然后 dict.iteritems()(及类似内容):返回一个生成器,因此您可以逐个迭代生成的每个值 dict.viewitems()(及类似内容)的用途是什么?它们的好处是什么?它是如何工作的?究竟什么是景观 我读到,这种观点总是反映出字典中的变化。但是从性能和内存的角度来看,它是如何工作的呢?优缺点是什么?视图方法返回一个列表(与.keys()、.it

在Python2.7中,我们得到了可用的

现在,我知道以下的利弊:

  • dict.items()
    (和
    ):返回一个列表,以便实际存储结果,然后
  • dict.iteritems()
    (及类似内容):返回一个生成器,因此您可以逐个迭代生成的每个值
dict.viewitems()
(及类似内容)的用途是什么?它们的好处是什么?它是如何工作的?究竟什么是景观


我读到,这种观点总是反映出字典中的变化。但是从性能和内存的角度来看,它是如何工作的呢?优缺点是什么?

视图方法返回一个列表(与
.keys()
.items()
.values()
相比,它不是列表的副本),因此它更轻量级,但反映了字典的当前内容

主要原因是,对于许多用例,返回一个完整的 分离列表是不必要和浪费的。这需要复制 整个内容(可能很多,也可能不是很多)

如果您只是想迭代这些键,那么创建一个新列表 没有必要。如果您确实需要它作为一个单独的列表(作为 复制)然后可以从视图轻松创建该列表


仅仅通过阅读文档,我就得到了这样的印象:

  • 视图是“伪集合式”的,因为它们不支持索引,所以您可以使用它们测试成员资格并对其进行迭代(因为键是可散列且唯一的,键和项视图更像“集合式”,因为它们不包含重复项)
  • 您可以存储它们并多次使用它们,就像列表版本一样
  • 因为它们反映了底层字典,所以字典中的任何更改都将改变视图,并且几乎肯定会改变迭代的顺序。因此,与列表版本不同,它们并不“稳定”
  • 因为它们反映了底层字典,所以几乎可以肯定它们是小的代理对象;复制键/值/项需要他们以某种方式查看原始字典,并在发生更改时复制多次,这将是一个荒谬的实现。所以我希望内存开销很小,但是访问速度比直接访问字典要慢一点

  • 所以我想关键的用例是,如果你保持一个字典,并反复迭代它的键/项/值,其间进行修改。您可以只使用视图,将mydict.iteritems()中k,v的
    转换为myview中k,v的
    。但是如果你只是在字典上迭代一次,我认为iter版本还是比较好的。

    字典视图基本上就是它们的名字所说的:视图就像字典键和值(或项)上的一个窗口。以下是Python3版本的摘录:

    >>> dishes = {'eggs': 2, 'sausage': 1, 'bacon': 1, 'spam': 500}
    >>> keys = dishes.keys()
    >>> values = dishes.values()
    
    >>> # view objects are dynamic and reflect dict changes
    >>> del dishes['eggs']
    >>> keys  # No eggs anymore!
    dict_keys(['sausage', 'bacon', 'spam'])
    
    >>> values  # No eggs value (2) anymore!
    dict_values([1, 1, 500])
    
    (Python2等价物使用
    disks.viewkeys()
    disks.viewvalues()

    此示例显示视图的动态特性:关键点视图不是给定时间点关键点的副本,而是显示关键点的简单窗口;如果它们被改变了,那么你通过窗口看到的也会改变。此功能在某些情况下非常有用(例如,可以使用程序多个部分中键的视图,而不是每次需要时重新计算当前键列表)-请注意,如果在视图上迭代时修改了字典键,则迭代器的行为未得到很好的定义,哪个可以

    一个优点是,例如,查看键只使用小而固定的内存量,并且需要小而固定的处理器时间,因为不需要创建键列表(另一方面,Python2经常不必要地创建一个新列表,正如Rajendran T所引用的那样,它占用的内存和时间与列表的长度成正比)。要继续窗口类比,如果你想看到墙后的风景,你只需在其中开一个口(你构建了一个窗口);将关键点复制到列表中相当于在墙上绘制风景的副本。副本需要时间、空间,并且不会自动更新


    总而言之,视图只是…视图(窗口)在您的字典上,即使字典发生更改,也会显示其内容。它们提供了与列表不同的功能:键列表包含给定时间点的字典键副本,而视图是动态的,获取速度更快,因为它不必复制任何数据(键或值)为了被创建。

    正如您提到的
    dict.items()
    返回字典的(键,值)对列表的副本,这是浪费的,
    dict.iteritems()
    返回字典的(键,值)对的迭代器

    现在以下面的例子来看dict的interator和dict视图之间的区别

    >>> d = {"x":5, "y":3}
    >>> iter = d.iteritems()
    >>> del d["x"]
    >>> for i in iter: print i
    ... 
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    RuntimeError: dictionary changed size during iteration
    

    视图只是字典现在的样子。删除条目后,
    .items()
    将过期,
    .iteritems()
    会引发错误。

    视图允许您访问参考底图数据结构,而无需复制它。除了作为动态视图而不是创建列表外,它们最有用的用法之一是在测试中使用
    。假设您想检查dict中是否有值(它是键还是值)

    选项一是使用
    dict.keys()
    创建一个密钥列表,这样做有效,但显然会消耗更多内存。如果dict非常大,那将是浪费

    使用
    视图
    可以迭代实际的数据结构,而无需中间列表

    让我们举个例子,我有一个包含1000个随机字符串和数字的dict
    >>> d = {"x":5, "y":3}
    >>> v = d.viewitems()
    >>> v
    dict_items([('y', 3), ('x', 5)])
    >>> del d["x"]
    >>> v
    dict_items([('y', 3)])
    
    large_d = { .. 'NBBDC': '0RMLH', 'E01AS': 'UAZIQ', 'G0SSL': '6117Y', 'LYBZ7': 'VC8JQ' .. }
    
    >>> len(large_d)
    1000
    
    # this is one option; It creates the keys() list every time, it's here just for the example
    timeit.timeit('k in large_d.keys()', setup='from __main__ import large_d, k', number=1000000)
    13.748743600954867
    
    
    # now let's create the list first; only then check for containment
    >>> list_keys = large_d.keys()
    >>> timeit.timeit('k in list_keys', setup='from __main__ import large_d, k, list_keys', number=1000000)
    8.874809793833492
    
    
    # this saves us ~5 seconds. Great!
    # let's try the views now
    >>> timeit.timeit('k in large_d.viewkeys()', setup='from __main__ import large_d, k', number=1000000)
    0.08828549011070663
    
    # How about saving another 8.5 seconds?