Python flatten list (but not all the way)

坚强是说给别人听的谎言 提交于 2019-12-24 12:12:48

问题


I have a list of lists of lists...

A = [ [[1,3]], [[3,5], [4,4], [[5,3]]] ]

the following function outputs [1, 3, 3, 5, 4, 4, 5, 3]

def flatten(a):
    b = []
    for c in a:
        if isinstance(c, list):
            b.extend(flatten(c))
        else:
            b.append(c)
    return b

However, I want to stop flattening on the last level so that I get [ [1,3], [3,5], [4,4], [5,3] ]


回答1:


You could test for contained lists before flattening:

def flatten(a):
    b = []
    for c in a:
        if isinstance(c, list) and any(isinstance(i, list) for i in c):
            b.extend(flatten(c))
        else:
            b.append(c)
    return b

Demo:

>>> def flatten(a):
...     b = []
...     for c in a:
...         if isinstance(c, list) and any(isinstance(i, list) for i in c):
...             b.extend(flatten(c))
...         else:
...             b.append(c)
...     return b
... 
>>> A = [ [[1,3]], [[3,5], [4,4], [[5,3]]] ]
>>> flatten(A)
[[1, 3], [3, 5], [4, 4], [5, 3]]

This tries to be as efficient as can be under the circumstances; any() only needs to test until a list is found, not all elements.




回答2:


A = [ [[1,3]], [[3,5], [4,4], [[5,3]]] ]

print [child[0] if isinstance(child[0], list) else child for item in A for child in item]

Output

[[1, 3], [3, 5], [4, 4], [5, 3]]

Note: This solution is strictly for this problem only. This is not a generic list flattening solution.

The same idea, with itertools.chain

from itertools import chain
print [item[0] if isinstance(child[0], list) else item for item in chain(*A)]

Output

[[1, 3], [3, 5], [4, 4], [5, 3]]


来源:https://stackoverflow.com/questions/19617334/python-flatten-list-but-not-all-the-way

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!