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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17485747/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 08:19:36  来源:igfitidea点击:

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

pythonpython-2.7nested-lists

提问by compski

I tried everything (in my knowledge) from splitting the array and joining them up together and even using itertools:

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

import itertools

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

The result I want:

我想要的结果:

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

一种) print oneDArray([1,[2,2,2],4]) == [1,2,2,2,4]

Strangely, it works for

奇怪的是,它适用于

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

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

Question 1) How do I get part a to work the way I want (any hints?)

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

Question 2) Why does the following code above work for part b and not part a??

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

采纳答案by Ashwini Chaudhary

You need to recursively loop over the list and check if an item is iterable(strings are iterable too, but skip them) or not.

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

itertools.chainwill not work for [1,[2,2,2],4]because it requires all of it's items to be iterable, but 1and 4(integers) are not iterable. That's why it worked for the second one because it's a list of lists.

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, basestring):
             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]

Works for any level of nesting:

适用于任何级别的嵌套:

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

Unlike other solutions, this will work for strings as well:

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

>>> lis = [1,[2,2,2],"456"]
>>> list(flatten(lis))
[1, 2, 2, 2, '456']

回答by TerryA

itertools.chain()iterates through each item in the inputted list (refer to the docs I linked). Because you can't iterate through integers, the error is raised. That is why in the second example, you only have lists in the list and no integers alone, thus no integers are actually being iterated through.

itertools.chain()遍历输入列表中的每个项目(请参阅我链接的文档)。因为您不能遍历整数,所以会引发错误。这就是为什么在第二个示例中,列表中只有列表,而没有单独的整数,因此实际上没有整数被迭代。

To get it working, you can use recursion:

为了让它工作,你可以使用递归:

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

回答by Pawel Miech

It's actually quite easy without using itertools, you can simply iterate over a list and if the loop will encounter another list you will simply iterate over nested list. Here's the code:

不使用 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]

回答by thiruvenkadam

If it is going to be only one level of list of lists, then the simplest solution is:

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

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

Why I used extend(list(item)) is that even if there is a set within your items, it will not cause any problem. This will handle items as string, integer, boolean, dictionary, list as well as a tuple.

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

回答by Ewan

If you're using python < 3then you can do the following:

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

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

The manual equivalent in python 3.0 would be (taken from this answer):

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"],[],[[]]]))  

You could even do the same in a list comprehension:

你甚至可以在列表理解中做同样的事情:

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

Which is the equivalent of:

这相当于:

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

print(result)

回答by Abhishek

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

Use recursion to convert multi nested list into single sliced list.

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

回答by Nabajeet Dhar

To Make A Single list from a Nested List in python we can simply do this :

要从 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)

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

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

回答by Brndn

from nltk import flatten

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

Output: [1, 2, 3, 3]

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

回答by AnujSingla

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)

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

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