使用生成器和迭代器时 Python 多循环失败

2022-01-10 00:00:00 python generator loops iterator

问题描述

我需要一个 2D 循环,其中第一个循环使用迭代器,第二个循环使用生成器,但是这个简单的函数无法工作,谁能帮忙检查一下?

I need a 2D loop of which the first loop uses an iterator and the second uses a generator, but this simple function failed to work, can anyone help to check?

def alphabet(begin, end):
    for number in xrange(ord(begin), ord(end)+1):
        yield chr(number)

def test(a, b):
    for i in a:
        for j in b:
            print i, j

test(xrange(8, 10), alphabet('A', 'C'))

The result shows:
>>> 8 A
>>> 8 B
>>> 8 c

不知道为什么?如果有人可以提供帮助,请提前致谢.

don't know why? thanks in advance if any one can help.


解决方案

既然你要求澄清,我就多说一点;但真的 Ignacio 的回答总结得很好:您只能迭代生成器一次.您示例中的代码尝试对其进行三次迭代,a 中的每个值一次.

Since you've asked for clarification, I'll say a bit more; but really Ignacio's answer sums it up pretty well: you can only iterate over a generator once. The code in your example tries to iterate over it three times, once for each value in a.

要明白我的意思,请考虑这个简单的例子:

To see what I mean, consider this simplistic example:

>>> def mygen(x):
...     i = 0
...     while i < x:
...         yield i
...         i += 1
... 
>>> mg = mygen(4)
>>> list(mg)
[0, 1, 2, 3]
>>> list(mg)
[]

mygen 被调用时,它会创建一个可以只迭代一次的对象.当您尝试再次对其进行迭代时,您会得到一个空的可迭代对象.

When mygen is called, it creates an object which can be iterated over exactly once. When you try to iterate over it again, you get an empty iterable.

这意味着你必须重新调用 mygen,每次你想要迭代它`.所以换句话说(使用相当冗长的风格)......

This means you have to call mygen anew, every time you want to iterate over it`. So in other words (using a rather verbose style)...

>>> def make_n_lists(gen, gen_args, n):
...     list_of_lists = []
...     for _ in range(n):
...         list_of_lists.append(list(gen(*gen_args)))
...     return list_of_lists
... 
>>> make_n_lists(mygen, (3,), 3)
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]

如果您想将参数绑定到生成器并将其作为无参数函数传递,您可以这样做(使用更简洁的样式):

If you wanted to bind your arguments to your generator and pass that as an argumentless function, you could do this (using a more terse style):

>>> def make_n_lists(gen_func, n):
...     return [list(gen_func()) for _ in range(n)]
... 
>>> make_n_lists(lambda: mygen(3), 3)
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]

lambda 只是定义了一个匿名函数;以上与此相同:

The lambda just defines an anonymous function; the above is identical to this:

>>> def call_mygen_with_3():
...     return mygen(3)
... 
>>> make_n_lists(call_mygen_with_3, 3)
[[0, 1, 2], [0, 1, 2], [0, 1, 2]]

相关文章