我正在学习python的生成器、迭代器、迭代器,我无法解释为什么下面的内容不能工作。作为练习,我想创建一个函数zip的简单版本。我所做的是:
def myzip(*collections):
iterables = tuple(iter(collection) for collection in collections)
yield tuple(next(iterable) for iterable in iterables)
test = myzip([1,2,3],(4,5,6),{7,8,9})
print(next(test))
print(next(test))
print(next(test))我所做的是:
collections,它是一些集合的一个元组iterables,其中对于每个集合(这是可迭代的),我使用iter获得迭代器。next。这个元组是屈服的。因此,我希望在第一次执行时创建(并存储)对象iterables。然后,在每次迭代(包括第一次迭代)中,我对存储在前面的每个可迭代性调用next并返回它。
然而,这是我得到的:
(1, 4, 8)
---------------------------------------------------------------------------
StopIteration Traceback (most recent call last)
<ipython-input-108-424963a58e58> in <module>()
8
9 print(next(test))
---> 10 print(next(test))
StopIteration: 所以我看到第一次迭代很好,结果是正确的。但是,第二次迭代会引发一个StopIteration异常,我不明白为什么:每个迭代仍然有一些值,所以next的任何一个返回StopIteration。事实上,这样做是可行的:
def myziptest(*collections):
iterables = tuple(iter(collection) for collection in collections)
for _ in range(3):
print(tuple(next(iterable) for iterable in iterables))
test = myziptest([1,2,3],(4,5,6),{7,8,9})输出:
(1, 4, 8)
(2, 5, 9)
(3, 6, 7)那是怎么回事?非常感谢
发布于 2017-05-08 15:07:01
这里有一个可行的解决方案
def myzip(*collections):
iterables = tuple(iter(collection) for collection in collections)
while True:
try:
yield tuple([next(iterable) for iterable in iterables])
except StopIteration:
# one of the iterables has no more left.
break
test = myzip([1,2,3],(4,5,6),{7,8,9})
print(next(test))
print(next(test))
print(next(test))此代码与您的代码之间的区别在于,您的代码只生成一个结果。也就是说,多次调用next将为您提供一个StopIteration。
将yield x看作是将x放入队列,而next则是从该队列中弹出。当您尝试从空队列中弹出时,您将得到Stopiteration。你只能弹出你放的那么多。
https://stackoverflow.com/questions/43849987
复制相似问题