代码之家  ›  专栏  ›  技术社区  ›  ThomasH

列表理解中的二次迭代

  •  166
  • ThomasH  · 技术社区  · 16 年前

    在python中,在一个列表理解中可以有多个迭代器,比如

    [(x,y) for x in a for y in b]
    

    对于一些合适的序列A和B,我知道Python列表理解的嵌套循环语义。

    我的问题是:理解中的一个迭代器可以引用另一个吗?换言之:我可以要这样的东西吗?

    [x for x in a for a in b]
    

    外部循环的当前值在哪里是内部循环的迭代器?

    例如,如果我有一个嵌套列表:

    a=[[1,2],[3,4]]
    

    为了达到这个结果,列表理解表达式是什么:

    [1,2,3,4]
    

    ??(请只列出理解答案,因为这是我想知道的)。

    8 回复  |  直到 7 年前
        1
  •  129
  •   André Eriksson    16 年前

    用你自己的建议来回答你的问题:

    >>> [x for b in a for x in b] # Works fine
    

    当你要求列表理解答案时,我还要指出优秀的itertools.chain():

    >>> from itertools import chain
    >>> list(chain.from_iterable(a))
    >>> list(chain(*a)) # If you're using python < 2.6
    
        2
  •  96
  •   ThomasH    16 年前

    哎呀,我想我找到了安wser:我对哪个循环是内部的,哪个循环是外部的考虑不够。列表理解应该如下:

    [x for b in a for x in b]
    

    为了得到所需的结果,是的,一个当前值可以是下一个循环的迭代器:-)。对不起,噪音太大了。

        3
  •  86
  •   Skam    10 年前

    我希望这能帮助别人 a,b,x,y 对我没有多大意义!假设你有一个充满句子的文本,你想要一组单词。

    # Without list comprehension
    list_of_words = []
    for sentence in text:
        for word in sentence:
           list_of_words.append(word)
    return list_of_words
    

    我喜欢把列表理解看作是水平扩展代码。

    试着把它分成:

    # List Comprehension 
    [word for sentence in text for word in sentence]
    
        4
  •  35
  •   Dima Tisnek    8 年前

    迭代器的顺序似乎有违直觉。

    例如: [str(x) for i in range(3) for x in foo(i)]

    让我们分解它:

    def foo(i):
        return i, i + 0.5
    
    [str(x)
        for i in range(3)
            for x in foo(i)
    ]
    
    # is same as
    for i in range(3):
        for x in foo(i):
            yield str(x)
    
        5
  •  17
  •   Martin Thoma    11 年前

    托马斯已经补充了一个很好的答案,但我想展示一下会发生什么:

    >>> a = [[1, 2], [3, 4]]
    >>> [x for x in b for b in a]
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    NameError: name 'b' is not defined
    
    >>> [x for b in a for x in b]
    [1, 2, 3, 4]
    >>> [x for x in b for b in a]
    [3, 3, 4, 4]
    

    我猜python从左到右解析列表理解。这意味着,第一个 for 将首先执行发生的循环。

    第二个问题是 b 从列表理解中“泄漏”出来。在第一次成功的列表理解之后 b == [3, 4] .

        6
  •  7
  •   steven    9 年前

    如果要保留多维数组,应嵌套数组括号。请参见下面的示例,其中每个元素都添加一个元素。

    >>> a = [[1, 2], [3, 4]]
    
    >>> [[col +1 for col in row] for row in a]
    [[2, 3], [4, 5]]
    
    >>> [col +1 for row in a for col in row]
    [2, 3, 4, 5]
    
        7
  •  3
  •   simP    9 年前

    此外,您可以对当前访问的输入列表成员使用相同的变量。 对于此成员内的元素。然而,这甚至可能使它更难以理解。

    input = [[1, 2], [3, 4]]
    [x for x in input for x in x]
    

    弗斯特 for x in input 被评估,导致输入的一个成员列表,然后,python遍历第二部分 for x in x 在这个过程中,x值被它正在访问的当前元素覆盖,然后第一个元素 x 定义我们要返回的内容。

        8
  •  2
  •   Opal    11 年前

    我觉得这更容易理解

    [row[i] for row in a for i in range(len(a))]
    
    result: [1, 2, 3, 4]