如何在Python中将嵌套列表转换为一维列表?[复制]

How to convert a nested list into a one-dimensional list in Python? [duplicate]

提问人:compski 提问时间:7/5/2013 最后编辑:Ashwini Chaudharycompski 更新时间:5/8/2022 访问量:105279

问:

我尝试了所有方法(据我所知),从拆分数组并将它们连接在一起 甚至使用 itertools:

import itertools

def oneDArray(x):
    return list(itertools.chain(*x))

我想要的结果:

a)print oneDArray([1,[2,2,2],4]) == [1,2,2,2,4]

奇怪的是,它适用于

b)print oneDArray([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) == [1, 2, 3, 4, 5, 6, 7, 8, 9]

问题 1) 如何让 a 部分按照我想要的方式工作(有什么提示吗?

问题 2) 为什么上面的以下代码适用于 b 部分而不是 a 部分?

蟒蛇-2.7 嵌套列表

评论

1赞 compski 7/5/2013
我在 SO 中找不到我想要的答案,因为我的搜索结果都没有返回任何关于“扁平化”的内容,但这里给出的答案帮助澄清了很多!

答:

28赞 Ashwini Chaudhary 7/5/2013 #1

您需要递归循环列表并检查项目是否可迭代(字符串也是可迭代的,但跳过它们)。

itertools.chain将不起作用,因为它要求它的所有项都是可迭代的,但 和 (整数) 是不可迭代的。这就是为什么它适用于第二个,因为它是一个列表列表。[1,[2,2,2],4]14

>>> from collections import Iterable
def flatten(lis):
     for item in lis:
         if isinstance(item, Iterable) and not isinstance(item, str):
             for x in flatten(item):
                 yield x
         else:        
             yield item

>>> lis = [1,[2,2,2],4]
>>> list(flatten(lis))
[1, 2, 2, 2, 4]
>>> list(flatten([[1, 2, 3], [4, 5, 6], [7, 8, 9]]))
[1, 2, 3, 4, 5, 6, 7, 8, 9]

适用于任何级别的嵌套:

>>> a = [1,[2,2,[2]],4]
>>> list(flatten(a))
[1, 2, 2, 2, 4]

与其他解决方案不同,这也适用于字符串:

>>> lis = [1,[2,2,2],"456"]
>>> list(flatten(lis))
[1, 2, 2, 2, '456']
2赞 TerryA 7/5/2013 #2

itertools.chain() 遍历输入列表中的每个项目(请参阅我链接的文档)。由于无法循环访问整数,因此会引发错误。这就是为什么在第二个示例中,列表中只有列表,而没有单独的整数,因此实际上没有整数被循环访问。

要让它工作,您可以使用递归:

>>> from collections import Iterable
>>> def flat(lst):
...     for parent in lst:
...         if not isinstance(i, Iterable):
...             yield parent
...         else:
...             for child in flat(parent):
...                 yield child
...
>>> list(flat(([1,[2,2,2],4]))
[1, 2, 2, 2, 4]
0赞 Pawel Miech 7/5/2013 #3

实际上,在不使用 itertools 的情况下,这很容易,您可以简单地遍历一个列表,如果循环会遇到另一个列表,您只需遍历嵌套列表即可。代码如下:

def flatten(l):
    flatList = []
    for elem in l:
        # if an element of a list is a list
        # iterate over this list and add elements to flatList 
        if type(elem) == list:
            for e in elem:
                flatList.append(e)
        else:
            flatList.append(elem)
    return flatList


a = [1,[2,2,2],4]  # flatten(a) returns [1, 2, 2, 2, 4]
b =  [[1, 2, 3], [4, 5, 6], [7, 8, 9]] # flatten(b) returns [1, 2, 3, 4, 5, 6, 7, 8, 9]
0赞 thiruvenkadam 7/5/2013 #4

如果它只是列表列表的一个级别,那么最简单的解决方案是:

lis = [1,[2,2,2],"456"]
output = []
for item in lis:
    if isinstance(item, (str, int, bool)):
        output.append(item)
    elif isinstance(item, dict):
        for i in item.items():
            output.extend(i)
    else:
        output.extend(list(item))

我为什么使用 extend(list(item)) 是因为即使您的项目中有一个集合,也不会造成任何问题。这将处理字符串、整数、布尔值、字典、列表以及元组等项目。

22赞 Ewan 7/5/2013 #5

如果您正在使用,则可以执行以下操作:python < 3

from compiler.ast import flatten
list = [1,[2,2,2],4]
print flatten(list)

python 3.0 中的手动等效项是(取自此答案):

def flatten(x):
    result = []
    for el in x:
        if hasattr(el, "__iter__") and not isinstance(el, str):
            result.extend(flatten(el))
        else:
            result.append(el)
    return result

 print(flatten(["junk",["nested stuff"],[],[[]]]))  

您甚至可以在列表推导中执行相同的操作:

list = [1,[2,2,2],4]
l = [item for sublist in list for item in sublist]

这相当于:

l = [[1], [2], [3], [4], [5]]
result = []
for sublist in l:
    for item in sublist:
        result.append(item)

print(result)
0赞 SaintGermain 7/5/2013 #6

你可能想看看这里:http://caolanmcmahon.com/posts/flatten_for_python/ http://rightfootin.blogspot.de/2006/09/more-on-python-flatten.html

0赞 Abhishek 7/12/2016 #7
old_list = [1,2,3,['a','b'],4,5,6,['c','d',[11,22,33,'aa','bb','cc',[111,222,333,['aaa','bbb','ccc',[1111,2222,['aaaa','bbbb',[11111,22222]]]]]],'e']]

new_list = []

def my_fun(temp_list):
    for ele in temp_list:
        if type(ele) == list:
            my_fun(ele)
        else:
            new_list.append(ele)


my_fun(old_list)
print old_list
print new_list

output:
old_list = [1, 2, 3, ['a', 'b'], 4, 5, 6, ['c', 'd', [11, 22, 33, 'aa', 'bb', 'cc', [111, 222, 333, ['aaa', 'bbb', 'ccc', [1111, 2222, ['aaaa', 'bbbb', [11111, 22222]]]]]], 'e']]
new_list = [1, 2, 3, 'a', 'b', 4, 5, 6, 'c', 'd', 11, 22, 33, 'aa', 'bb', 'cc', 111, 222, 333, 'aaa', 'bbb', 'ccc', 1111, 2222, 'aaaa', 'bbbb', 11111, 22222, 'e']

使用递归将多嵌套列表转换为单个切片列表。

10赞 Nabajeet Dhar 2/1/2019 #8

要在python中从嵌套列表制作单个列表,我们可以简单地这样做:

from functools import reduce

some_list = [[14], [215, 383, 87], [298], [374], [2,3,4,5,6,7]]
single_list = reduce(lambda x,y: x+y, some_list)
print(single_list)

输出:[14, 215, 383, 87, 298, 374, 2, 3, 4, 5, 6, 7]

6赞 Brndn 11/28/2019 #9
from nltk import flatten

example_list = [1, [2, 3], 3]
flattened_list = flatten(example_list)
print(flattened_list)

输出:[1、2、3、3]

0赞 AnujSingla 12/27/2019 #10
def flatten_out_nested_list(input_list):
    if input_list is None:
        return None
    if not isinstance(input_list, (list, tuple)):
        return None
    flattened_list = []
    for entry in input_list:
        entry_list = None
        if not isinstance(entry, list):
            try:
                entry_list = ast.literal_eval(entry)
            except:
                pass
        if not entry_list:
            entry_list = entry
        if isinstance(entry_list, list):
            flattened_entry = flatten_out_nested_list(entry_list)
            if flattened_entry:
                flattened_list.extend(flattened_entry)
        else:
            flattened_list.append(entry)
    return flattened_list

nested_list = [[1,2,3,4,5],[6,7,8,9,10]]
flattened_list = flatten_out_nested_list(nested_list)

输出: [1,2,3,4,5,6,7,8,9,10]

2赞 Akshay Kumbharkar 2/5/2020 #11

使用more_itertools

import more_itertools

nested_test1 = [[-1, -2], [1, 2, 3, [4, (5, [6, 7])]], (30, 40), [25, 35]]
nested_test2 = [1,[2,2,2],4]
lis = [1,[2,2,2],"456"]

print(list(more_itertools.collapse(nested_test1)))
print(list(more_itertools.collapse(nested_test2)))
print(list(more_itertools.collapse(lis)))

输出

[-1, -2, 1, 2, 3, 4, 5, 6, 7, 30, 40, 25, 35]
[1, 2, 2, 2, 4]
[1, 2, 2, 2, '456']
0赞 ravibeli 5/4/2020 #12

此 flatten_nlevel 函数将展平 n 级嵌套列表或将其转换为一个级别。试试这个

def flatten_nlevel(list1, flat_list):
    for sublist in list1:
        if isinstance(sublist, type(list)):        
            flatten(sublist, flat_list)
        else:
            flat_list.append(sublist)

list1 = [1,[1,[2,3,[4,6]],4],5]

items = []
flatten(l,items)
print(items)

输出:

[1, 1, 2, 3, 4, 6, 4, 5]
2赞 Ghaith Alsirawan 7/29/2020 #13

您不必使用 .只需使用appendextend

def flatten(nasted_list):
    """
    input: nasted_list - this contain any number of nested lists.
    ------------------------
    output: list_of_lists - one list contain all the items.
    """

    list_of_lists = []
    for item in nasted_list:
        list_of_lists.extend(item)
    return list_of_lists

test1 = flatten([[1,2,3],[4,5,6]])
print(test1)

输出:[1, 2, 3, 4, 5, 6]

0赞 TBhavnani 2/23/2022 #14

使用管道包

from pipe import chain


lst=[[1,2], [3,4], [5,6]]

list(lst|chain)

[1, 2, 3, 4, 5, 6]

0赞 user16495813 4/30/2022 #15
list1 = [[1,2,3], 2, 4,[4,5,6],[7,8,9]] 
flat_list = []
for item in list1:
    if type(item) == list:
        flat_list = flat_list+item
    else:
        flat_list.append(item)

输出:[1、2、3、2、4、4、5、6、7、8、9]