在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]
?? (请只列出理解性的答案,因为这是我想知道的)。
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]。
假设你有一个充满句子的文本,你想要一个单词数组。
# 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?
这个flat_nlevel函数递归调用嵌套的list1来转换到一个级别。试试这个
def flatten_nlevel(list1, flat_list):
for sublist in list1:
if isinstance(sublist, type(list)):
flatten_nlevel(sublist, flat_list)
else:
flat_list.append(sublist)
list1 = [1,[1,[2,3,[4,6]],4],5]
items = []
flatten_nlevel(list1,items)
print(items)
输出:
[1, 1, 2, 3, 4, 6, 4, 5]
如果你想保持多维数组,就应该嵌套数组括号。参见下面的示例,其中每个元素都添加了一个。
>>> 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]