我觉得我错过了一些明显的东西,但它是......我想从以下地方出发:
lst = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], 2]
为:
output = [0, 1, 3, 7, 8, 11, 12, 8, 0, 1, 2, 3, 14, 2]
我可以使用for循环执行此操作,例如:
output = []
for l in lst:
if hasattr(l, '__iter__'):
output.extend(l)
else:
output.append(l)
也许for-loop很好,但感觉应该有更优雅的方式来做这个...尝试用numpy做这个似乎更复杂,因为不好的数组不容易处理..所以你不能(例如):
output = np.asanyarray(lst).flatten().tolist()
提前致谢。
更新
这是我对@ T.J和@Ashwini提供的两种方法的比较 - 感谢两者!
In [5]: %paste
from itertools import chain
from collections import Iterable
lis = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], 2]
def solve(lis):
for x in lis:
if isinstance(x, Iterable) and not isinstance(x, basestring):
yield x
else:
yield [x]
%timeit list(chain.from_iterable(solve(lis)))
%timeit [a for x in lis for a in (x if isinstance(x, Iterable) and not isinstance(x,basestring) else [x])]
## -- End pasted text --
100000 loops, best of 3: 10.1 us per loop
100000 loops, best of 3: 8.12 us per loop
UPDATE2:
...
lis = lis *10**5
%timeit list(chain.from_iterable(solve(lis)))
%timeit [a for x in lis for a in (x if isinstance(x, Iterable) and not isinstance(x,basestring) else [x])]
## -- End pasted text --
1 loops, best of 3: 699 ms per loop
1 loops, best of 3: 698 ms per loop
答案 0 :(得分:2)
您可以像这样使用itertools.chain
:
>>> from itertools import chain
>>> from collections import Iterable
>>> lis = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], 2]
def solve(lis):
for x in lis:
if isinstance(x, Iterable) and not isinstance(x, basestring):
yield x
else:
yield [x]
...
>>> list(chain.from_iterable(solve(lis)))
[0, 1, 3, 7, 8, 11, 12, 8, 0, 1, 2, 3, 14, 2]
也适用于字符串:
>>> lis = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], "234"]
>>> list(chain.from_iterable(solve(lis)))
[0, 1, 3, 7, 8, 11, 12, 8, 0, 1, 2, 3, 14, '234']
时间比较:
>>> lis = lis *(10**4)
#modified version of FJ's answer that works for strings as well
>>> %timeit [a for x in lis for a in (x if isinstance(x, Iterable) and not isinstance(x,basestring) else [x])]
10 loops, best of 3: 110 ms per loop
>>> %timeit list(chain.from_iterable(solve(lis)))
1 loops, best of 3: 98.3 ms per loop
答案 1 :(得分:1)
这是一个使用列表理解的非常简单的方法:
>>> data = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], 2]
>>> [a for x in data for a in (x if isinstance(x, list) else [x])]
[0, 1, 3, 7, 8, 11, 12, 8, 0, 1, 2, 3, 14, 2]
以下是时序比较,看起来我的版本稍快一点(注意我修改了我的代码以使用collections.Iterable
以确保比较公平):
In [9]: %timeit list(chain.from_iterable(solve(data)))
100000 loops, best of 3: 9.22 us per loop
In [10]: %timeit [a for x in data for a in (x if isinstance(x, Iterable) else [x])]
100000 loops, best of 3: 6.45 us per loop
答案 2 :(得分:0)
您可以使用生成器使列表仅包含可迭代
((i if isinstance(i,Iterable) else [i])
然后使用以下任何方法将它们连接到一个列表中:
你会尝试sum
from collections import Iterable
lis = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], 2]
sum(((i if isinstance(i,Iterable) else [i]) for i in lis), [])
您应该提供总和[]
的初始值,以便从
或itertools.chain()
但在这种情况下,您应该将您的上级列表解压缩到一组列表
import itertools
lis = [[0, 1, 3, 7, 8, 11, 12], [8, 0, 1, 2, 3, 14], 2]
list(itertools.chain(*((i if isinstance(i,Iterable) else [i]) for i in lis)))
或只列出理解
[a for x in input for a in (x if isinstance(x, Iterable) else [x])]
但是人们应该注意字符串也是可迭代的。并且如果在上层将有字符串,它将被激活到字符中。