问题
I have a list of objects where objects can be lists or scalars. I want an flattened list with only scalars. Eg:
L = [35,53,[525,6743],64,63,[743,754,757]]
outputList = [35,53,525,6743,64,63,743,754,757]
P.S. The answers in this question does not work for heterogeneous lists. Flattening a shallow list in Python
回答1:
Here is a relatively simple recursive version which will flatten any depth of list
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)
回答2:
it could be done neatly in one line using numpy
import numpy as np
np.hstack(l)
you end up with an ndarray
array([ 35, 53, 525, 6743, 64, 63, 743, 754, 757])
回答3:
>>> 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]
Here is a one-liner version for code-golf purposes (it doesn't look good :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]
回答4:
l = [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)
回答5:
Here's a oneliner, based on the question you've mentioned:
list(itertools.chain(*((sl if isinstance(sl, list) else [sl]) for sl in l)))
UPDATE: And a fully iterator-based version:
from itertools import imap, chain
list(chain.from_iterable(imap(lambda x: x if isinstance(x, list) else [x], l)))
回答6:
outputList = []
for e in l:
if type(e) == list:
outputList += e
else:
outputList.append(e)
>>> outputList
[35, 53, 525, 6743, 64, 63, 743, 754, 757]
回答7:
def nchain(iterable):
for elem in iterable:
if type(elem) is list:
for elem2 in elem:
yield elem2
else:
yield elem
回答8:
Recursive function that will allow for infinite tree depth:
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]
I tried to avoid isinstance so as to allow for generic types, but old version would infinite loop on strings. Now it flattens strings correctly (Not by characters now, but as if it's pretending a string is a scalar).
回答9:
>>> 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]
回答10:
This solution is only for your specific situation (scalars within lists) and assumes the scalars are integer. It is a terrible solution but it is incredibly short.
outputlist = map(int,",".split(str(L).replace("[","").replace("]","")))
回答11:
The answer is quite simple. Take advantage of recursion.
def flatten(nst_lst, final_list):
for val in nst_lst:
if isinstance(val, list):
flatten(val, final_list)
else:
final_list.append(val)
return final_list
#Sample usage
fl_list = []
lst_to_flatten = [["this",["a",["thing"],"a"],"is"],["a","easy"]]
print(flatten(lst_to_flatten, fl_list))
来源:https://stackoverflow.com/questions/10632111/how-to-flatten-a-hetrogenous-list-of-list-into-a-single-list-in-python