在Python中,some_dict.items()是一个迭代器吗?

7
我对迭代器和可迭代对象之间的区别有些困惑。我已经阅读了很多资料,大致了解如下:
迭代器:一个类中包含__next__方法的对象。你可以在它上面调用next()方法。所有迭代器都是可迭代对象。
可迭代对象:一个类中定义了__iter__或__getitem__方法的对象。如果使用iter()函数可以构建一个迭代器,则该对象是可迭代的。并非所有可迭代对象都是迭代器。
一些_dict.items()是一个迭代器吗?我知道在Python2中,some_dict.iteritems()是迭代器。我只是想确认一下,因为我正在参加一门课程,它说它是一个迭代器,但我相当确定它只是一个可迭代对象。
谢谢你的帮助 :)

@ytu 不是真正的重复问题,在我看来,无论如何,被接受的答案错误地解决了这个问题的具体细节。 - juanpa.arrivillaga
@juanpa.arrivillaga 我知道被接受的答案是不正确的。但是那里的讨论已经涵盖了很多内容,足以解决这个问题。 - ytu
我有一种感觉,你并没有问你想问的问题。 items() 确实不返回迭代器,但它返回的东西表现得像一个迭代器,所以你不应该关心它。换句话说,它不像 Python 2 中那样创建所有项的列表,而是在你遍历它们时逐个生成。 - zvone
1
@zvone 但是你不能在items上调用next(),所以它肯定不像迭代器一样工作?关于重复,我之前读过那个答案,但感觉它可能不够简单易懂:P 现在再回头看结合这里的答案,我明白了,所以如果这是共识,我很乐意接受重复(我对stackoverflow还很新)。 - Ed the Coder
1
@E.Hazledine - 是的,但我猜OP想知道它是否像Python 2中的“items”一样行为,还是像“iteritems”,在这种情况下,所有正确的答案都会导致错误的结论。因此,我的评论简化了问题。 - zvone
4个回答

7
不,它不是。它是字典中项目的可迭代视图:
>>> next({}.items())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'dict_items' object is not an iterator
>>>

它的 __iter__ 方法返回一个特殊的迭代器实例:

>>> iter({}.items())
<dict_itemiterator object at 0x10478c1d8>
>>>

3
您可以直接进行测试:
from collections import Iterator, Iterable

a = {}
print(isinstance(a, Iterator))  # -> False
print(isinstance(a, Iterable))  # -> True
print(isinstance(a.items(), Iterator))  # -> False
print(isinstance(a.items(), Iterable))  # -> True

3

dict.items 返回一个 字典视图,根据 文档

In [5]: d = {1: 2}

In [6]: next(d.items())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-6-945b6258a834> in <module>()
----> 1 next(d.items())

TypeError: 'dict_items' object is not an iterator

In [7]: next(iter(d.items()))
Out[7]: (1, 2)

回答你的问题,dict.items不是迭代器。它是一个可迭代对象,支持len__contains__方法,并反映原始字典所做的更改。
In [14]: d = {1: 2, 3: 4}

In [15]: it = iter(d.items())

In [16]: next(it)
Out[16]: (1, 2)

In [17]: d[3] = 5

In [18]: next(it)
Out[18]: (3, 5)

2

请自行检查:

d = {'a': 1, 'b': 2}

it = d.items()
print(next(it))

这会导致 TypeError: 'dict_items' object is not an iterator 错误。

另一方面,您始终可以通过以下方式迭代 d.items()

d = {'a': 1, 'b': 2}

for k, v in d.items():
    print(k, v)

或者:

d = {'a': 1, 'b': 2}

it = iter(d.items())
print(next(it))  # ('a', 1)
print(next(it))  # ('b', 2)

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