列表推导中的双重迭代

401 投票
11 回答
371343 浏览
提问于 2025-04-15 13:14

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

??(请只给出列表推导式的答案,因为这正是我想要了解的)。

11 个回答

202

为了回答你的问题,我用你自己的建议来说明:

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

假设你有一段包含很多句子的文本,你想把这些句子里的单词提取成一个数组。

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

例子:

>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> [word for sentence in text for word in sentence]
['Hi', 'Steve!', "What's", 'up?']

这同样适用于生成器。

>>> text = (("Hi", "Steve!"), ("What's", "up?"))
>>> gen = (word for sentence in text for word in sentence)
>>> for word in gen: print(word)
Hi
Steve!
What's
up?
162

哎呀,我想我找到了答案:我没有注意到哪个循环是内层的,哪个是外层的。列表推导式应该像这样:

[x for b in a for x in b]

这样才能得到想要的结果。对了,一个当前的值可以作为下一个循环的迭代器。

撰写回答