24

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

import itertools

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

我想要的结果:

一个)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部分?

4

14 回答 14

24

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

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']
于 2013-07-05T09:42:58.733 回答
17

如果您正在使用,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)
于 2013-07-05T10:38:41.940 回答
10

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

于 2019-02-01T12:22:50.727 回答
6
from nltk import flatten

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

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

于 2019-11-28T06:13:26.687 回答
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]
于 2013-07-05T09:43:25.703 回答
2

使用 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']
于 2020-02-05T07:09:33.667 回答
1

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

于 2020-07-29T11:26:58.503 回答
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]
于 2013-07-05T09:58:13.133 回答
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)) 是即使你的items中有一个set,也不会造成任何问题。这会将项目处理为字符串、整数、布尔值、字典、列表以及元组。

于 2013-07-05T10:34:05.367 回答
0

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

于 2013-07-05T10:42:46.720 回答
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']

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

于 2016-07-12T11:46:53.830 回答
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]

于 2019-12-26T21:31:44.343 回答
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]
于 2020-05-04T12:05:01.447 回答
0

使用管道包

from pipe import chain


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

list(lst|chain)

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

于 2022-02-23T07:07:02.833 回答