如何从列表中创建一个简单的列表?

时间 2009-06-05
阅读 1317995
点赞 2315
收藏 766
连接emma

我想知道是否有一个快捷方式可以在python中从列表中创建一个简单的列表。

我可以做一个for循环,但也许有一些酷的“一行”?我试过了减少但我得到一个错误。

代码

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'
✅ 被采纳的答案
flat_list = [item for sublist in l for item in sublist]

这意味着:

for sublist in l:
    for item in sublist:
        flat_list.append(item)

比目前张贴的快捷方式快。(l是要展平的列表。)

以下是相应的函数:

flatten = lambda l: [item for sublist in l for item in sublist]

作为证据,一如既往,你可以使用timeit标准库中的模块:

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

说明:快捷方式基于+(包括在sum)必要时,O(L**2)当存在l个子列表时——由于中间结果列表不断变长,在每个步骤中都会分配一个新的中间结果列表对象,并且必须复制上一个中间结果中的所有项(以及在末尾添加的一些新项)。所以(为了简单和没有实际的通用性损失)假设您有每个i项的l个子列表:第一个i项被前后复制l-1次,第二个i项被复制l-2次,依此类推;总的复制数是x的x的和的i倍,从1到l被排除,也就是说,I * (L**2)/2.

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

👍 3331