关于python:如何展平列表以返回包含所有元素的新列表?

How to flatten a list to return a new list with all the elements?

我正在尝试编写一个名为flatten_list的函数,该函数将一个可能嵌套的列表作为输入,并返回一个包含输入列表中所有元素的非嵌套列表。

我的代码:

1
2
3
4
5
6
7
8
9
10
11
def flatten_list(alist):
   """
    >>> flatten_list([1,2,3])
    [1, 2, 3]
    >>> flatten_list([1, [2,3], [4, 5], 6])
    [1, 2, 3, 4, 5, 6]
   """

    flat_list = []
    for element in alist:
        flat_list += element
    return flat_list

此代码适用于带有字符串的列表,但不适用于整数值。如何更改代码以使其同时适用于这两种情况?

谢谢


通常,这将以递归方式进行,例如:

1
2
3
4
5
6
7
8
9
10
11
12
def flatten(input_, output=None):
    if output is None:
        output = []
    if isinstance(input_, basestring):
        output.append(input_)
    else:
        for item in input_:
            try:
                flatten(item, output)
            except TypeError:
                output.append(item)
    return output

这将适用于使用通用EAFP python样式的任何可重复容器(例如,setlisttupledict(仅限密钥)和内容(例如,intfloatstr的组合。请注意字符串的特定异常,您可能不希望解包这些字符串!

一些用法示例:

1
2
3
4
5
6
7
8
>>> flatten([1, [2, [3, [4, 5], 6], 7], 8])
[1, 2, 3, 4, 5, 6, 7, 8]
>>> flatten([1,"foo", ["bar", 2], 3])
[1, 'foo', 'bar', 2, 3]
>>> flatten([1, (2, 3), {4: 5}])
[1, 2, 3, 4]
>>> flatten("hello")
['hello']

非iterables作为直接论点会发生什么:

1
2
3
4
5
6
7
8
>>> flatten(1)

Traceback (most recent call last):
  File"<pyshell#3>", line 1, in <module>
    flatten(1)
  File"<pyshell#1>", line 4, in flatten
    for item in input_:
TypeError: 'int' object is not iterable

使用集合.iterable

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
from collections import Iterable
def flatten(items):
    for elem in items:
        if isinstance(elem,Iterable) and not isinstance(elem,str):
            for sub_elem in flatten(elem):
                yield sub_elem
        else:
            yield elem




 In [15]:   print list(flatten((1, (2,3), [4, 5],{10,11,12}, 6)))
 [1, 2, 3, 4, 5, 10, 11, 12, 6]


 In [16]: print list(flatten((1, (2,3), (4,5,6), 6)))
 [1, 2, 3, 4, 5, 6, 6]

 In [17]: print list(flatten([1,"foo", ["bar", 2], 3]))
 [1, 'foo', 'bar', 2, 3]


你可以这样做:

1
2
3
4
5
6
7
8
9
10
11
12
a = [1, [2,3], [4, 5], 6]

def flatten(l,result = []):
    if isinstance(l, list):
        for i in l:
            flatten(i)
    else:
        result.append(l)
    return result

>>> print flatten(a)
[1, 2, 3, 4, 5, 6]

这将适用于更深层的嵌套级别:

1
2
>>> print flatten([1, [2, [3, 4]]])
[1, 2, 3, 4]

演示