有没有一种简单的方法可以用列表理解来扁平化可迭代列表,或者如果不能做到这一点,你们都会认为什么是扁平化这样一个浅层列表的最好方法,以平衡性能和可读性呢?

我试图用嵌套的列表理解将这样的列表展平,如下所示:

[image for image in menuitem for menuitem in list_of_menuitems]

但我遇到了NameError种的麻烦,因为name 'menuitem' is not defined种.在谷歌搜索并查看堆栈溢出后,我用reduce语句得到了想要的结果:

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

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

Conclusion:

感谢为这个问题做出贡献的每一个人.这是我所学知识的总结.我还将此设置为社区维基,以防其他人想要添加或更正这些观察到的内容.

我最初的reduce语句是多余的,最好这样写:

>>> 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来避免*operator magic可能是更好的方式,比如:

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

推荐答案

如果您只是希望迭代数据 struct 的平面化版本,并且不需要可索引的序列,请考虑itertools.chain and company.

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

它将适用于任何iterable,包括Django的iterable QuerySet,这似乎是你在问题中使用的.

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

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

Edit:J.F. Sebastian says一样itertools.chain.from_iterable避免了解包,您应该使用这一点来避免*魔术,但是the timeit app显示的性能差异可以忽略不计.

Python相关问答推荐

为什么使用SciPy中的Distance. cos函数比直接执行其Python代码更快?

Python在通过Inbox调用时给出不同的响应

Python:MultiIndex Dataframe到类似json的字典列表

Flask:如何在完整路由代码执行之前返回验证

我可以使用极点优化这个面向cpu的pandas代码吗?

Altair -箱形图边界设置为黑色,中线设置为红色

Tkinter滑动条标签.我不确定如何删除滑动块标签或更改其文本

ambda将时间戳与组内另一列的所有时间戳进行比较

覆盖Django rest响应,仅返回PK

Python中是否有方法从公共域检索搜索结果

在应用循环中间保存pandas DataFrame

仅从风格中获取 colored颜色 循环

通过优化空间在Python中的饼图中添加标签

Deliveryter Notebook -无法在for循环中更新matplotlib情节(保留之前的情节),也无法使用动画子功能对情节进行动画

抓取rotowire MLB球员新闻并使用Python形成表格

如何获取TFIDF Transformer中的值?

如何让程序打印新段落上的每一行?

基于索引值的Pandas DataFrame条件填充

如何在turtle中不使用write()来绘制填充字母(例如OEG)

重置PD帧中的值