在Python中,有没有一种快捷方式可以从列表列表中生成一个简单的列表?

我可以在for圈内完成,但是有没有很酷的"俏皮话"呢?

我试了functools.reduce()次:

from functools import reduce
l = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
reduce(lambda x, y: x.extend(y), l)

但我有一个错误:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 1, in <lambda>
AttributeError: 'NoneType' object has no attribute 'extend'

推荐答案

给定列表t的列表,

flat_list = [item for sublist in t for item in sublist]

也就是说:

flat_list = []
for sublist in t:
    for item in sublist:
        flat_list.append(item)

比目前发布的快捷方式更快.(t是要展平的列表.)

下面是相应的函数:

def flatten(t):
    return [item for sublist in t for item in sublist]

作为证据,您可以使用标准库中的timeit模块:

$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in t for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(t, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s't=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,t)'
1000 loops, best of 3: 1.1 msec per loop

说明:当有T个子列表时,基于+的快捷方式(包括sum中的隐含用法)必然是O(T**2)--随着中间结果列表不断变长,在每一步都会分配一个新的中间结果列表对象,并且必须复制前一个中间结果中的所有项(以及在末尾添加的几个新项).因此,为简单起见,在不丧失一般性的情况下,假设您有T个子列表,每个子列表包含k个项目:前k个项目来回复制T-1次,后k个项目复制T-2次,依此类推;副本总数是x从1到T之和的k倍,即k * (T**2)/2.

列表理解只生成一个列表,只需一次,并且将每个项目(从其原始居住地复制到结果列表)也恰好复制一次.

Python相关问答推荐

Python中MongoDB的BSON时间戳

如何使用scipy从频谱图中回归多个高斯峰?

将DF中的名称与另一DF拆分并匹配并返回匹配的公司

TARete错误:类型对象任务没有属性模型'

为什么我的Python代码在if-else声明中的行之前执行if-else声明中的行?

Pandas 滚动最接近的价值

不理解Value错误:在Python中使用迭代对象设置时必须具有相等的len键和值

切片包括面具的第一个实例在内的眼镜的最佳方法是什么?

为什么以这种方式调用pd.ExcelWriter会创建无效的文件格式或扩展名?

为什么NumPy的向量化计算在将向量存储为类属性时较慢?'

在Django admin中自动完成相关字段筛选

多处理队列在与Forking http.server一起使用时随机跳过项目

在www.example.com中使用`package_data`包含不包含__init__. py的非Python文件

合并帧,但不按合并键排序

如何使用两个关键函数来排序一个多索引框架?

Python—转换日期:价目表到新行

(Python/Pandas)基于列中非缺失值的子集DataFrame

如何使用正则表达式修改toml文件中指定字段中的参数值

以异步方式填充Pandas 数据帧

如何强制向量中的特定元素在Gekko中处于优化解决方案中