Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
169 views
in Technique[技术] by (71.8m points)

python - 如何从列表列表中制作平面列表?(How to make a flat list out of list of lists?)

I wonder whether there is a shortcut to make a simple list out of list of lists in Python.

(我想知道是否有捷径可以从Python的列表清单中做出一个简单的清单。)

I can do that in a for loop, but maybe there is some cool "one-liner"?

(我可以在for循环中执行此操作,但是也许有一些很酷的“单行代码”?)

I tried it with reduce() , but I get an error.

(我用reduce()尝试过,但是出现错误。)

Code

()

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

Error message

(错误信息)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Given a list of lists l ,

(给定一个列表l ,)

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

which means:

(意思是:)

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

is faster than the shortcuts posted so far.

(比到目前为止发布的快捷方式快。)

( l is the list to flatten.)

(( l是要扁平化的列表。))

Here is the corresponding function:

(这是相应的功能:)

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

As evidence, you can use the timeit module in the standard library:

(作为证明,您可以使用标准库中的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

Explanation: the shortcuts based on + (including the implied use in sum ) are, of necessity, O(L**2) when there are L sublists -- as the intermediate result list keeps getting longer, at each step a new intermediate result list object gets allocated, and all the items in the previous intermediate result must be copied over (as well as a few new ones added at the end).

(说明:当有L个子列表时,基于+的快捷方式(包括sum的隐含使用)必然为O(L**2) -由于中间结果列表越来越长,因此每一步都有一个新的中间结果将分配list对象,并且必须复制上一个中间结果中的所有项目(以及最后添加的一些新项目)。)

So, for simplicity and without actual loss of generality, say you have L sublists of I items each: the first I items are copied back and forth L-1 times, the second I items L-2 times, and so on;

(因此,为简单起见,而又不失去一般性,请说您有I个项目的L个子列表:第一个I项目来回复制L-1次,第二个I项目L-2次,依此类推;等等。)

total number of copies is I times the sum of x for x from 1 to L excluded, ie, I * (L**2)/2 .

(总拷贝数是I乘以x的x的总和(从1到L排除在外),即I * (L**2)/2 。)

The list comprehension just generates one list, once, and copies each item over (from its original place of residence to the result list) also exactly once.

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...