是空元组(takewhile())在Python中推进我的迭代器吗?

时间:2018-04-20 10:35:36

标签: python

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)

1 个答案:

答案 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

这意味着您只能迭代迭代器对象一次