在python中将列表列表加入单个列表(或迭代器)的简短语法是什么?
例如,我有一个如下列表,我想迭代a,b和c.
x = [["a","b"], ["c"]]
Run Code Online (Sandbox Code Playgroud)
我能想到的最好的是如下.
result = []
[ result.extend(el) for el in x]
for el in result:
print el
Run Code Online (Sandbox Code Playgroud)
CTT*_*CTT 424
import itertools
a = [['a','b'], ['c']]
print(list(itertools.chain.from_iterable(a)))
Run Code Online (Sandbox Code Playgroud)
Geo*_*lly 169
如果你只是深入一级,嵌套的理解也会起作用:
>>> x = [["a","b"], ["c"]]
>>> [inner
... for outer in x
... for inner in outer]
['a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)
在一行,这成为:
>>> [j for i in x for j in i]
['a', 'b', 'c']
Run Code Online (Sandbox Code Playgroud)
CMS*_*CMS 147
x = [["a","b"], ["c"]]
result = sum(x, [])
Run Code Online (Sandbox Code Playgroud)
Pao*_*ino 29
这被称为展平,并且有很多实现:
这个怎么样,虽然它只适用于1级深度嵌套:
>>> x = [["a","b"], ["c"]]
>>> for el in sum(x, []):
... print el
...
a
b
c
Run Code Online (Sandbox Code Playgroud)
从这些链接,显然最完整,快速优雅等实现如下:
def flatten(l, ltypes=(list, tuple)):
ltype = type(l)
l = list(l)
i = 0
while i < len(l):
while isinstance(l[i], ltypes):
if not l[i]:
l.pop(i)
i -= 1
break
else:
l[i:i + 1] = l[i]
i += 1
return ltype(l)
Run Code Online (Sandbox Code Playgroud)
nat*_*e c 27
l = []
map(l.extend, list_of_lists)
Run Code Online (Sandbox Code Playgroud)
最短!
Geo*_*lly 15
这对于无限嵌套元素递归工作:
def iterFlatten(root):
if isinstance(root, (list, tuple)):
for element in root:
for e in iterFlatten(element):
yield e
else:
yield root
Run Code Online (Sandbox Code Playgroud)
结果:
>>> b = [["a", ("b", "c")], "d"] >>> list(iterFlatten(b)) ['a', 'b', 'c', 'd']
Evg*_*eev 11
性能比较:
import itertools
import timeit
big_list = [[0]*1000 for i in range(1000)]
timeit.repeat(lambda: list(itertools.chain.from_iterable(big_list)), number=100)
timeit.repeat(lambda: list(itertools.chain(*big_list)), number=100)
timeit.repeat(lambda: (lambda b: map(b.extend, big_list))([]), number=100)
timeit.repeat(lambda: [el for list_ in big_list for el in list_], number=100)
[100*x for x in timeit.repeat(lambda: sum(big_list, []), number=1)]
Run Code Online (Sandbox Code Playgroud)
生产:
>>> import itertools
>>> import timeit
>>> big_list = [[0]*1000 for i in range(1000)]
>>> timeit.repeat(lambda: list(itertools.chain.from_iterable(big_list)), number=100)
[3.016212113769325, 3.0148865239060227, 3.0126415732791028]
>>> timeit.repeat(lambda: list(itertools.chain(*big_list)), number=100)
[3.019953987082083, 3.528754223385439, 3.02181439266457]
>>> timeit.repeat(lambda: (lambda b: map(b.extend, big_list))([]), number=100)
[1.812084445152557, 1.7702404451095965, 1.7722977998725362]
>>> timeit.repeat(lambda: [el for list_ in big_list for el in list_], number=100)
[5.409658160700605, 5.477502077679354, 5.444318360412744]
>>> [100*x for x in timeit.repeat(lambda: sum(big_list, []), number=1)]
[399.27587954973444, 400.9240571138051, 403.7521153804846]
Run Code Online (Sandbox Code Playgroud)
这是在Windows XP 32位上的Python 2.7.1,但上面的评论中的@temoto from_iterable
必须更快map+extend
,因此它非常依赖于平台和输入.
保持距离 sum(big_list, [])
迟到了,但......
我是python的新手,来自lisp背景.这就是我提出的(查看lulz的var名称):
def flatten(lst):
if lst:
car,*cdr=lst
if isinstance(car,(list,tuple)):
if cdr: return flatten(car) + flatten(cdr)
return flatten(car)
if cdr: return [car] + flatten(cdr)
return [car]
Run Code Online (Sandbox Code Playgroud)
似乎工作.测试:
flatten((1,2,3,(4,5,6,(7,8,(((1,2)))))))
Run Code Online (Sandbox Code Playgroud)
收益:
[1, 2, 3, 4, 5, 6, 7, 8, 1, 2]
Run Code Online (Sandbox Code Playgroud)
您所描述的内容被称为展平列表,利用这些新知识,您将能够在Google上找到许多解决方案(没有内置的展平方法).以下是其中之一,来自http://www.daniel-lemire.com/blog/archives/2006/05/10/flattening-lists-in-python/:
def flatten(x):
flat = True
ans = []
for i in x:
if ( i.__class__ is list):
ans = flatten(i)
else:
ans.append(i)
return ans
Run Code Online (Sandbox Code Playgroud)
如果需要列表而不是生成器,请使用 list():
from itertools import chain
x = [["a","b"], ["c"]]
y = list(chain(*x))
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
314525 次 |
最近记录: |