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

时间:2013-07-05 09:40:41

标签: python python-2.7 nested-lists

我尝试了一切(据我所知)分裂数组并将它们连接在一起 甚至使用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)我如何按照我想要的方式获得工作(任何提示?)

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

13 个答案:

答案 0 :(得分:11)

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

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

python 3.0中的手册等价物(取自this answer):

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)

答案 1 :(得分:8)

你需要递归循环遍历列表并检查一个项是否可迭代(字符串也是可迭代的,但是跳过它们)或不是。

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]

适用于任何级别的嵌套:

>>> 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 :(得分:1)

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]

答案 3 :(得分:1)

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

答案 4 :(得分:0)

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

答案 5 :(得分:0)

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

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))是即使你的项目中有一个集合,也不会导致任何问题。这将把项目处理为字符串,整数,布尔值,字典,列表以及元组。

答案 6 :(得分:0)

答案 7 :(得分:0)

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

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

答案 8 :(得分:0)

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

答案 9 :(得分:0)

from nltk import flatten

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

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

答案 10 :(得分:0)

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]

答案 11 :(得分:0)

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

答案 12 :(得分:0)

您不必使用append。只需使用extend

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]