Python 3.5.4
如果我将list_iterator传递给takewhile,然后遍历takewhile对象,则list_iterator会被提升,即使takewhile对象没有任何内容也是如此。当我传递一个范围对象时,这不会发生。如果这是预期的行为,那么我有一些东西需要学习。
def range_vs_iter():
# expected works as expected. surprise does not.
expected = range(5)
surprise = iter([0, 1, 2, 3, 4])
# both of these produce an empty tuple
print(tuple(takewhile(lambda x: False, expected)))
print(tuple(takewhile(lambda x: False, surprise)))
# the first element in surprise has disappeared
print(tuple(expected)) # (0, 1, 2, 3, 4)
print(tuple(surprise)) # (1, 2, 3, 4)
# if I don't iterate over takewhile object, everything is fine
my_iter = iter([0, 1, 2, 3, 4])
takewhile(lambda x: False, my_iter)
print(tuple(my_iter)) # (0, 1, 2, 3, 4)
答案 0 :(得分:1)
您的问题可以简化为:
In [9]: expected = range(5)
In [10]: surprise = iter([0, 1, 2, 3, 4])
In [11]: list(expected)
Out[11]: [0, 1, 2, 3, 4]
In [12]: list(expected)
Out[12]: [0, 1, 2, 3, 4]
In [13]: list(surprise)
Out[13]: [0, 1, 2, 3, 4]
In [14]: list(surprise)
Out[14]: []
这是因为range
是每次有人调用__iter__
时产生新迭代器的对象:
In [19]: expected.__iter__() is expected.__iter__()
Out[19]: False
但是,在迭代器上调用__iter__
将始终返回相同的对象:
In [18]: surprise.__iter__() is surprise.__iter__()
Out[18]: True
这意味着您只能迭代迭代器对象一次