是否有一种简单的方法可以用列表理解来扁平化一个可迭代对象列表,或者如果没有,你们都认为什么是扁平化这样一个浅列表的最好方法,平衡性能和可读性?
我尝试用一个嵌套的列表理解来扁平化这样一个列表,就像这样:
[image for image in menuitem for menuitem in list_of_menuitems]
但我在那里遇到了NameError
类型的麻烦,因为name 'menuitem' is not defined
。在google和Stack Overflow上查找之后,我用reduce
语句得到了想要的结果:
reduce(list.__add__, map(lambda x: list(x), list_of_menuitems))
但这个方法是相当不可读的,因为我需要list(x)
调用,因为x是Django的QuerySet
对象。
结论:
感谢每个为这个问题做出贡献的人。以下是我所学到的一份总结。我也把它变成了一个社区维基,以防其他人想要添加或纠正这些观察。
我原来的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
来避免*操作符魔法可能是更好的风格:
>>> chain = itertools.chain.from_iterable([[1,2],[3],[5,89],[],[6]])
>>> print(list(chain))
>>> [1, 2, 3, 5, 89, 6]