【问题标题】:Python multi-loop failed when with generator and iterator使用生成器和迭代器时 Python 多循环失败
【发布时间】:2012-05-04 16:17:38
【问题描述】:

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

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

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

【问题讨论】:

    标签: python loops iterator generator


    【解决方案1】:

    b 的第一次迭代消耗了生成器。

    【讨论】:

    • 抱歉,您能说得更具体点吗?
    【解决方案2】:

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

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

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

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

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

    >>> 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]]
    

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

    >>> 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 只是定义了一个匿名函数;以上与此相同:

    >>> 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]]
    

    【讨论】:

    • 谢谢,您的帖子很有帮助。
    猜你喜欢
    • 1970-01-01
    • 2018-05-06
    • 1970-01-01
    • 1970-01-01
    • 2018-11-01
    • 2017-08-06
    • 2015-06-06
    • 2016-03-23
    • 2013-08-09
    相关资源
    最近更新 更多