列表理解中的双重迭代

在Python中,您可以在列表理解中使用多个迭代器

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

对于一些合适的序列a和b。 我知道Python列表parsing的嵌套循环语义。

我的问题是:理解中的一个迭代器可以引用另一个吗? 换句话说:我可以有这样的东西:

 [x for x in a for a in b] 

外层循环的当前值是内层的迭代器?

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

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

列表理解expression式是为了达到这个结果:

 [1,2,3,4] 

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

用自己的build议回答你的问题:

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

啧啧,我想我find了一个答案:我没有充分考虑哪个圈是内圈,哪圈是外圈。 列表理解应该是这样的:

 [x for b in a for x in b] 

得到想要的结果,是的,一个当前值可以是下一个循环的迭代器:-)。 对不起,噪音。

我希望这可以帮助别人,因为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] 

ThomasH已经添加了一个很好的答案,但是我想说明会发生什么:

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

我猜Pythonparsing从左到右的列表理解。 这意味着,第一个for循环会先执行。

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

迭代器的顺序可能看起来不符合直觉。

例如: [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) ] # if same as for i in range(3): for x in foo(i): yield str(x) 

如果要保留multidimensional array,则应该嵌套数组括号。 看下面的例子,其中一个被添加到每个元素。

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

我觉得这更容易理解

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

另外,您可以对当前访问的input列表的成员以及该成员内的元素使用相同的variables。 但是,这甚至可能使它更多(列表)不可理解。

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

首先for x in input进行求值,得到input的一个成员列表,然后,Python遍历for x in x的第二部分for x in x期间,x值被正在访问的当前元素覆盖,然后第一个x定义我们想要返回的。