问题

这个问题已经有一个答案:

  • 2001年12月31日终了的两年期收入和支出及准备金和基金结余变动报表 javascript – 如何在列表中创建一个统一列表 2001年12月31日终了的两年期收入和支出及准备金和基金结余变动报表 45个答案 2001年12月31日终了的两年期收入和支出及准备金和基金结余变动报表 2001年12月31日终了的两年期收入和支出及准备金和基金结余变动报表

有没有一种简单的方法来打平具有列表理解的迭代列表,或者失败,你们都认为是最好的方法来打平这样的浅列表,平衡性能和可读性?

我试图用嵌套列表理解压缩这样的列表,如下所示:

 [image for image in menuitem for menuitem in list_of_menuitems]
 

但我在那里遇到了NameError品种的麻烦,因为name 'menuitem' is not defined.谷歌搜索并查看Stack Overflow之后,我得到了所需的结果,使用reduce语句:

 reduce(list.__add__, map(lambda x: list(x), list_of_menuitems))
 

但这个方法相当不可读,因为我需要list(x)调用它,因为x是一个Django QuerySet对象.

结论:

感谢为这个问题作出贡献的每个人.这是我所学到的内容的摘要.我也在使这成为一个社区维基,以防其他人想要添加或纠正这些观察.

我的原始减少语句是多余的,最好以这种方式写:

 >>> reduce(list.__add__, (list(mi) for mi in list_of_menuitems))
 

这是嵌套列表理解的正确语法(Brilliant summary dF !):

 >>> [image for mi in list_of_menuitems for image in mi]
 

但是这些方法都不像使用itertools.chain那样有效:

 >>> from itertools import chain
>>> list(chain(*list_of_menuitems))
 

正如@cdleary注意到的那样,通过使用chain.from_iterable来避免*运算符魔法可能更好:

 >>> chain = itertools.chain.from_iterable([[1,2],[3],[5,89],[],[6]])
>>> print(list(chain))
>>> [1, 2, 3, 5, 89, 6]
 

  最佳答案

如果您只是想迭代一个平坦版本的数据结构,并且不需要一个可索引的序列,请考虑 itertools.chain 和

 >>> list_of_menuitems = [['image00', 'image01'], ['image10'], []]
>>> import itertools
>>> chain = itertools.chain(*list_of_menuitems)
>>> print(list(chain))
['image00', 'image01', 'image10']
 

它将处理任何可迭代的东西,其中应包括Django可迭代的QuerySets,这似乎是你在问题中使用的.

编辑:无论如何,这可能与减少一样好,因为减少将有相同的开销将项目复制到扩展的列表中.如果最后运行list(chain),chain只会产生此(相同)开销.

Meta-Edit:实际上,它的开销比问题提出的解决方案少,因为当你使用临时扩展原始时,你会丢弃你创建的临时列表。

编辑:由于 J.F. Sebastian说 itertools.chain.from_iterable避免解包,您应该使用它来避免*魔术,但时间应用显示微不足道的性能差异.

  相同标签的其他问题

pythonlist-comprehension