Double Iteration in List Comprehension
在python中,在一个列表理解中可以有多个迭代器,比如
1 | [(x,y) for x in a for y in b] |
对于一些合适的序列A和B,我知道Python列表理解的嵌套循环语义。
我的问题是:理解中的一个迭代器可以引用另一个吗?换言之:我可以要这样的东西吗?
1 | [x for x in a for a in b] |
外部循环的当前值在哪里是内部循环的迭代器?
例如,如果我有一个嵌套列表:
1 | a=[[1,2],[3,4]] |
为了达到这个结果,列表理解表达式是什么:
1 | [1,2,3,4] |
??(请只列出理解答案,因为这是我想知道的)。
用你自己的建议来回答你的问题:
1 | >>> [x for b in a for x in b] # Works fine |
当你要求列出理解答案时,我还要指出优秀的itertools.chain():
1 2 3 | >>> from itertools import chain >>> list(chain.from_iterable(a)) >>> list(chain(*a)) # If you're using python < 2.6 |
哎呀,我想我找到了一个答案:我对哪一个环是内部的,哪一个环是外部的考虑不够。列表理解应该如下:
1 | [x for b in a for x in b] |
为了得到所需的结果,是的,一个当前值可以是下一个循环的迭代器。
我希望这对其他人有帮助,因为
1 2 3 4 5 6 | # Without list comprehension list_of_words = [] for sentence in text: for word in sentence: list_of_words.append(word) return list_of_words |
我喜欢把列表理解看作是水平扩展代码。
试着把它分成:
1 2 | # List Comprehension [word for sentence in text for word in sentence] |
迭代器的顺序似乎有违直觉。
例如:
让我们分解它:
1 2 3 4 5 6 7 8 9 10 11 12 | 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) |
托马斯已经补充了一个很好的答案,但我想展示一下会发生什么:
1 2 3 4 5 6 7 8 9 10 | >>> 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从左到右解析列表理解。这意味着,发生的第一个
第二个"问题"是,
如果要保留多维数组,应嵌套数组括号。请参见下面的示例,其中每个元素都添加一个元素。
1 2 3 4 5 6 7 | >>> 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] |
此外,对于当前访问的输入列表的成员和此成员内的元素,可以使用相同的变量。然而,这甚至可能使它更难以理解。
1 2 | input = [[1, 2], [3, 4]] [x for x in input for x in x] |
首先对
我觉得这更容易理解
1 2 3 | [row[i] for row in a for i in range(len(a))] result: [1, 2, 3, 4] |