在Python中使用list(dict.items())和dict.items()迭代字典的区别在哪里?



我想知道为什么有这两种方法来遍历字典

states = {
'Oregon': 'OR',
'Florida': 'FL',
'California': 'CA',
'New York': 'NY',
'Michigan': 'MI'
}
for key, item in states.items():
print(key, item)
for key, item in list(states.items()):
print(key, item

据我所知,他们也是这样做的。还是有区别?

在这个特殊的例子中它们是一样的。如您所见:

>>> states.items()
dict_items([('Oregon', 'OR'), ('Florida', 'FL'), ('California', 'CA'), ('New York', 'NY'), ('Michigan', 'MI')])
>>> type(_)
<class 'dict_items'>
>>> 

items函数返回一个dict_items对象。

它有一个__iter__属性:

>>> dir(states.items())
['__and__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'isdisjoint']
>>> 

这意味着它支持迭代。

但是如果你想用它做任何事情:

>>> states.items()[0]
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
states.items()[0]
TypeError: 'dict_items' object is not subscriptable
>>> 

它会给出一个TypeError

dict_items类类似于:

class dict_items:
...
def __iter__(self):
...

它只支持迭代。

然而如果你把它转换成list:

>>> list(states.items())
[('Oregon', 'OR'), ('Florida', 'FL'), ('California', 'CA'), ('New York', 'NY'), ('Michigan', 'MI')]
>>> 

它将给出一个常规的元组列表,这显然也是可迭代的,但在这种情况下完全不需要。

@juanpa。arrivillaga提到,使用list(states.items())不必要地创建一个元组列表并迭代它,而不是直接迭代items-view。

在其他一些情况下,需要使用list。如果你想把一个字典转换成一个元组列表,list(states.items())是最好的选择。

您可能希望遍历项列表的主要原因是它允许您在迭代期间修改字典,向字典添加新项或删除旧项。

如果直接遍历字典并进行这样的修改,迭代将报错并崩溃。

如果您只修改属于现有键的值,它不会崩溃,但在这种情况下,与列表的迭代给您旧的值,而在字典上迭代直接给您当前的值(可能已经在早期项目中更改)。获取旧值可能是你想要的,例如,如果你编写一个生活游戏模拟器,需要从旧状态计算下一个状态,而不影响下一个状态的计算。

不需要是一个列表,只需要是项的某个副本,所以你不需要直接遍历字典。例如,可以使用tuple, dequeue甚至dict。

如果你不想修改,只是像你的玩具示例一样打印,那么创建列表只是毫无意义的浪费内存和时间。

最新更新