我有一个对象列表,其中对象可以是列表或标量。我想要一个只包含标量的平坦列表。 例如:
L = [35,53,[525,6743],64,63,[743,754,757]]
outputList = [35,53,525,6743,64,63,743,754,757]
注意:此问题中的答案不适用于异构列表。
Python 中扁平化浅层列表我有一个对象列表,其中对象可以是列表或标量。我想要一个只包含标量的平坦列表。 例如:
L = [35,53,[525,6743],64,63,[743,754,757]]
outputList = [35,53,525,6743,64,63,743,754,757]
注意:此问题中的答案不适用于异构列表。
Python 中扁平化浅层列表这是一个相对简单的递归版本,它可以展平任何深度的列表。
l = [35,53,[525,6743],64,63,[743,754,757]]
def flatten(xs):
result = []
if isinstance(xs, (list, tuple)):
for x in xs:
result.extend(flatten(x))
else:
result.append(xs)
return result
print flatten(l)
isinstance(xs,collections.Iterable) and not isinstance(xs,str)
,这样它就可以包括 set
和其他可能的可迭代对象了。 - balkiand not isinstance(xs, basestring)
,但这是个好主意。 - Nick Craig-Wood使用numpy
可以整洁地一行完成。
import numpy as np
np.hstack(l)
array([ 35, 53, 525, 6743, 64, 63, 743, 754, 757])
>>> data = [35,53,[525,6743],64,63,[743,754,757]]
>>> def flatten(L):
for item in L:
if isinstance(item,list):
for subitem in item:
yield subitem
else:
yield item
>>> list(flatten(data))
[35, 53, 525, 6743, 64, 63, 743, 754, 757]
这里是一行代码高尔夫的版本(它看起来不太好:D)
>>> [y for x in data for y in (x if isinstance(x,list) else [x])]
[35, 53, 525, 6743, 64, 63, 743, 754, 757]
hasattr(item, '__iter__')
,则可以避免字符串问题,而不限制可迭代范围。 - Joel Cornettlist
,所以我会像其他答案一样使用 isinstance
。 - jamylakl = [35,53,[525,6743],64,63,[743,754,757]]
outputList = []
for i in l:
if isinstance(i, list):
outputList.extend(i)
else:
outputList.append(i)
这是一个基于你提到的问题的一行代码:
list(itertools.chain(*((sl if isinstance(sl, list) else [sl]) for sl in l)))
更新:还有一个完全基于迭代器的版本:
from itertools import imap, chain
list(chain.from_iterable(imap(lambda x: x if isinstance(x, list) else [x], l)))
sum((i if isinstance(i, list) else [i] for i in L), [])
。 - Joel CornettoutputList = []
for e in l:
if type(e) == list:
outputList += e
else:
outputList.append(e)
>>> outputList
[35, 53, 525, 6743, 64, 63, 743, 754, 757]
def nchain(iterable):
for elem in iterable:
if type(elem) is list:
for elem2 in elem:
yield elem2
else:
yield elem
递归函数,允许无限树深度:
def flatten(l):
if isinstance(l,(list,tuple)):
if len(l):
return flatten(l[0]) + flatten(l[1:])
return []
else:
return [l]
>>>flatten([35,53,[525,[1,2],6743],64,63,[743,754,757]])
[35, 53, 525, 1, 2, 6743, 64, 63, 743, 754, 757]
我试图避免使用isinstance以允许通用类型,但旧版本会在字符串上无限循环。现在它可以正确地展开字符串(不再是按字符展开,而是像假装字符串是标量一样)。
>>> L = [35,53,[525,6743],64,63,[743,754,757]]
>>> K = []
>>> [K.extend([i]) if type(i) == int else K.extend(i) for i in L ]
[None, None, None, None, None, None]
>>> K
[35, 53, 525, 6743, 64, 63, 743, 754, 757]
这个解决方案仅适用于您特定的情况(列表中的标量),并假设标量为整数。这是一个可怕的解决方案,但它非常简短。
outputlist = map(int,",".split(str(L).replace("[","").replace("]","")))