list(dict)和dict.keys()之间的区别是什么?

23

假设我有一个字典:

foo = {'a': 1}

list(foo)foo.keys() 都返回相同的结果,它们之间有什么区别?


1
在Python3中,foo.keys()返回一个view - NightShadeQueen
注意,list()调用将基本上遍历从__iter__返回的对象,因此如果你在一个类中重写了dict__iter__,然后在它上调用.keys()list(),那么只有list()调用将运行新的__iter__ - Ashwini Chaudhary
5个回答

27

一个区别在于Python 3中foo.keys()返回的是键的迭代器,这与Python 2中foo.iterkeys()的作用相同,而list(foo)返回的是键的列表。

如下所述,Python 3中的foo.keys()并不完全返回一个迭代器。它返回一个dict_keys对象(或视图),其中包括迭代操作。您还可以进行有趣的操作,例如集合操作和多次迭代。它仍然具有迭代器的惰性求值概念,使得它们非常强大。


在Python 2中,list(foo)本质上调用了foo.iterkeys()并从其内容创建一个列表,因为foo.iterkeys()iter(foo)返回相同的对象。 - chepner
2
是的,还要查看文档 - https://docs.python.org/3/tutorial/datastructures.html - 脚注中的最后一点。dict.keys() 返回一个字典视图对象(而不是迭代器)。 - Anand S Kumar

9

Python3:

来自官方 文档

调用foo.keys()将返回一个字典视图对象。它支持成员测试和迭代等操作,但其内容不独立于原始字典 - 它只是一个视图。

事实上,

type(foo.keys())

提供

<class 'dict_keys'>

而在Python 2中,两者都

type(list(foo))
type(foo.keys())

提供

<type 'list'>

7

在Python 2中,dict.keysdict.viewkeys并没有什么真正的区别,这就是我怀疑为什么在Python3中dict.keys变成了可视图(view)并且移除了dict.viewkeys

在Python 3中:

In [3]: foo = dict((k,k) for k in range(4))

In [4]: foo
Out[4]: {0: 0, 1: 1, 2: 2, 3: 3}

In [5]: foo.keys?
Type:        builtin_function_or_method
String form: <built-in method keys of dict object at 0x7f45d8667708>
Docstring:   D.keys() -> a set-like object providing a view on D's keys

In [6]: foo.keys()
Out[6]: dict_keys([0, 1, 2, 3])

In [7]: type(foo.keys())
Out[7]: dict_keys

In [8]: for i in foo.keys():
   ...:     del foo[i]
   ...:     
---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-8-659d5446ab29> in <module>()
----> 1 for i in foo.keys():
      2     del foo[i]
      3 

RuntimeError: dictionary changed size during iteration

In [9]: for i in list(foo):
    del foo[i]

In [10]: foo
Out[10]: {}

最后两件事基本上是你需要了解的关于Python3中dict.keyslist(dictionary)之间的区别。 dict.keys仅仅是键的视图,因此检查item in dictionary.keys()是O(1),但您不能同时遍历dictionary.keys()并修改字典。 它们都是迭代器,因为它们都实现了__iter__

list(foo) 给你一个全新的列表对象,对吧?这就是为什么你可以从中删除项目,我想 :) - Pynchia
是的,这就是为什么你可以遍历它并从字典中删除。 - NightShadeQueen
foo.keys? 表示什么?在我的代码中好像不起作用。 - lang2
这是ipython的魔法,可以在这里看到第四个要点:http://pages.physics.cornell.edu/~myers/teaching/ComputationalMethods/python/ipython.html。它基本上相当于调用`help(foo.keys)`。 - NightShadeQueen

1
在Python 3中,.keys()返回的dict_keys对象只是指向实际字典键(并且在字典更改时更改),而list命令则创建键的副本。 因此,dict_keys更轻量级和更快。在迭代其键时修改字典时应使用list。以下是一个稍微有些荒谬的示例,其中字典为foo:
>>> for kw in foo.keys():
...   foo.pop(kw)

导致 RuntimeError: dictionary changed size during iteration,而以下代码可以正常工作:

>>> for kw in list(foo):
...   foo.pop(kw)

0
      'duration': [120.0, 240.0, 90.0, 16.0, 48.0],
      'rate': [0.11, 0.06, 0.08, 0.14, 0.07],
      'down_payment': [100000.0, 0.0, 8900.0, 0.0, 4300.0]} ```

data.keys()

dict_keys(['amount', 'duration', 'rate', 'down_payment'])

dict.keys produce a dictkeys. that we can only read . not can do change

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接