gpt4 book ai didi

python - 理解列表理解以展平 python 中的列表列表

转载 作者:太空狗 更新时间:2023-10-29 19:34:10 24 4
gpt4 key购买 nike

我发现这种理解非常适合展平列表列表:

>>> list_of_lists = [(1,2,3),(2,3,4),(3,4,5)]
>>> [item for sublist in list_of_lists for item in sublist]
[1, 2, 3, 2, 3, 4, 3, 4, 5]

与使用 itertools.chain() 相比,我更喜欢它,但我就是无法理解它。我试过用括号包围部分,看看是否可以降低复杂性,但现在我更加困惑了:

>>> [(item for sublist in list_of_lists) for item in sublist]
[<generator object <genexpr> at 0x7ff919fdfd20>, <generator object <genexpr> at 0x7ff919fdfd70>, <generator object <genexpr> at 0x7ff919fdfdc0>]

>>> [item for sublist in (list_of_lists for item in sublist)]
[5, 5, 5]

我感觉自己很难理解,因为我不太理解生成器的工作原理……我的意思是,我以为我理解了,但现在我很怀疑。就像我说的,我喜欢这个惯用语的简洁性,它正是我所需要的,但我不愿意使用我不理解的代码。

谁能解释一下这里到底发生了什么?

最佳答案

列表理解

当我第一次开始使用列表理解时,我像阅读英语句子一样阅读它,并且能够轻松理解它们。例如,

[item for sublist in list_of_lists for item in sublist]

可以这样读

for each sublist in list_of_lists and for each item in sublist add item

此外,过滤部分可以理解为

for each sublist in list_of_lists and for each item in sublist add item only if it is valid

对应的理解是

[item for sublist in list_of_lists for item in sublist if valid(item)]

生成器

它们就像地雷,只有在使用 next 协议(protocol)调用时才会触发。它们类似于函数,但在引发异常或到达函数末尾之前,它们不会耗尽并且可以一次又一次地调用。重要的是,它们保留了上次调用和当前调用之间的状态。

生成器和函数之间的区别在于,生成器使用 yield 关键字将值返回给调用程序。在生成器表达式的情况下,它们类似于列表理解,第一个表达式是“产生”的实际值。

有了这个基本的理解,如果我们看你在问题中的表达,

[(item for sublist in list_of_lists) for item in sublist]

您将列表理解与生成器表达式混合在一起。这将像这样阅读

for each item in sublist add a generator expression which is defined as, for every sublist in list_of_lists yield item

这不是你想的那样。并且由于不迭代生成器表达式,因此生成器表达式对象按原样添加到列表中。因为它们不会在没有被下一个协议(protocol)调用的情况下被评估,所以它们不会产生任何错误(如果有的话,除非它们有语法错误)。在这种情况下,它将产生运行时错误,因为 sublist 尚未定义。

此外,在最后一种情况下,

[item for sublist in (list_of_lists for item in sublist)]
for each sublist in the generator expression, add item and the generator expression is defined as for each item in sublist yield list_of_lists.

for 循环将使用下一个协议(protocol)迭代任何可迭代对象。因此,将评估生成器表达式,item 将始终是 sublist 迭代中的最后一个元素,您将其添加到列表中。这也会产生运行时错误,因为尚未定义子列表。

关于python - 理解列表理解以展平 python 中的列表列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24586757/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com