在Python中,你可以在一个列表推导式中有多个迭代器,比如

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

我知道Python的列表推导式的嵌套循环语义。

我的问题是:理解中的一个迭代器可以指向另一个迭代器吗?换句话说:我能得到这样的东西吗?

[x for x in a for a in b]

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

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

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

要实现这个结果,列表理解表达式是什么:

[1,2,3,4]

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


当前回答

假设你有一个充满句子的文本,你想要一个单词数组。

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

其他回答

假设你有一个充满句子的文本,你想要一个单词数组。

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

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

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

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]

我猜Python是从左到右解析列表理解的。这意味着,发生的第一个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)
]

# is same as
for i in range(3):
    for x in foo(i):
        yield str(x)

我觉得这样更容易理解

[row[i] for row in a for i in range(len(a))]

result: [1, 2, 3, 4]