2012-05-17 70 views
4

我有一个对象列表,其中的对象可以是列表或标量。我想要一个只有标量的扁平列表。例如:如何在python中将列表的hetrogenous列表拼合成单个列表?

L = [35,53,[525,6743],64,63,[743,754,757]] 
outputList = [35,53,525,6743,64,63,743,754,757] 

P.S.这个问题的答案不适用于异构列表。 Flattening a shallow list in Python

+0

这个作品,如果pop()方法返回在时间只有一个标量http://stackoverflow.com/a/10546929/1321404你可以与如果len(returned_pop_element)> 1,则调用递归函数修改此代码再次为returned_pop_element(列表)。 –

+0

另请参阅:http://stackoverflow.com/questions/5828123/nested-list-and-count/5828872 – sateesh

+0

[Flatten(不规则)列表在Python中]的可能重复(http://stackoverflow.com/问题/ 2158395/flatten-an-irregular-list-of-python) –

回答

6

这是一个比较简单的递归版本,这将拉平列表中的任何深度

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) 
+0

我想我可以使它成为'isinstance(xs,collections.Iterable)而不是isinstance(xs,str)',这样它就包含'set'和其他可能的iterables。 – balki

+0

'而不是isinstance(xs,basestring)'python <3,但是好主意 –

3
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) 
+0

@jamylak,感谢编辑,但我喜欢两个空格缩进:-( – Vikas

+1

[PEP 8!](http:// www .python.org/dev/peps/pep-0008 /#indentation) – jamylak

+0

@jamylak,谢谢你的参考。我一直认为建议使用空格。不知道是4个空格。 – Vikas

1

这里有一个oneliner,基于the question you've mentioned

list(itertools.chain(*((sl if isinstance(sl, list) else [sl]) for sl in l))) 

UPDATE:而且完全基于迭代器的版本:

from itertools import imap, chain 
list(chain.from_iterable(imap(lambda x: x if isinstance(x, list) else [x], l))) 
+1

这有点伤害了我的眼睛。 – jamylak

+0

这是一个oneliner,它不是很漂亮。 – ubik

+1

那么在这种情况下,我认为我有一个更小的班轮,我会发布它。 – jamylak

1
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] 
0
def nchain(iterable): 
    for elem in iterable: 
     if type(elem) is list: 
      for elem2 in elem: 
       yield elem2 
     else: 
      yield elem 
4

它可以使用一个线整齐地做numpy

import numpy as np 
np.hstack(l) 

你结束了一个ndarray

array([ 35, 53, 525, 6743, 64, 63, 743, 754, 757]) 
0

将允许树深度无限的递归函数:

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,以便允许泛型类型,但旧版本会无限循环的字符串。现在它正确地平整了字符串(现在不是通过字符,而是假装它是一个标量字符串)。

+0

我不希望字符串变平(破坏为单个字符)。 –

+0

从技术上讲,字符串是可迭代的,这就是为什么我将它包含在内的原因。当我更仔细地观察它时,看起来有些奇怪。 – Josiah

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] 

这里是代码高尔夫球场的目的一个班轮版本(它看起来并不好: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] 
+1

第一个版本将字符串分解为字符,我不认为这是可取的。 –

+0

@JanneKarila它不会说会有字符串。 – jamylak

+0

它说[标量](http://en.wikipedia.org/wiki/Scalar_(计算)) –

0
>>> 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] 
0

该解决方案是只针对您的具体情况中(标量列表)并假定标量是整数。这是一个可怕的解决方案,但它非常短。

outputlist = map(int,",".split(str(L).replace("[","").replace("]",""))) 
0

答案很简单。利用递归。

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)) 
相关问题