列表列表列表中的普通列表

plain list from list of lists of lists

我有一个这样的列表:

list1=[['milk', 'bread', 'eggs'], ['eggs', ['milk'], 'bread']]

我想拉平(预期结果):

list1=[['milk', 'bread', 'eggs'], ['eggs', 'milk', 'bread']]

我正在使用此代码:

flat_list = []
for sublist in list1:
    for item in sublist:
        flat_list.append(item)

但我回来了:

list1=['milk', 'bread', 'eggs', 'eggs', ['milk'], 'bread']

有什么想法吗?

这是可以解决您问题的代码

list1 = [['milk', 'bread', 'eggs'], ['eggs', ['milk'], 'bread']]

flat_list = []
for i in list1:
    temp_list =[]
    for j in i:
        if type(j) is list:
            temp_list.append(j[0])
        else:
            temp_list.append(j)
    flat_list.append(temp_list)

现在 flat_list 输出是

[['milk', 'bread', 'eggs'], ['eggs', 'milk', 'bread']]

您可以使用递归生成器以任意嵌套级别展平列表(仅受递归深度限制):

list1=[['milk', 'bread', 'eggs'], ['eggs', ['milk'], 'bread']]

def flatten(iterable):
    from collections.abc import Iterable
    for item in iterable:
        if isinstance(item, Iterable) and not isinstance(item, str):
            yield from flatten(item)
        else:
            yield item
            
list(flatten(list1))

输出:['milk', 'bread', 'eggs', 'eggs', 'milk', 'bread']

仅在第一级后展平:

out = [list(flatten(l)) for l in list1]

输出:[['milk', 'bread', 'eggs'], ['eggs', 'milk', 'bread']]

您可以检查您是否正在点击一个列表,如果它是一个列表,则扩展它,如果不是附加它。

flat_list = []
for sublist in list1:
    flat_list.append([])
    for x in sublist:
        if isinstance(x, list):
            flat_list[-1].extend(x)
        else:
            flat_list[-1].append(x)

输出:

[['milk', 'bread', 'eggs'], ['eggs', 'milk', 'bread']]

但是如果你有这样的东西,这将不起作用:

[['milk', ['bread', ['eggs']]]]

或者你可以使用下面的函数(不使用递归,所以会更快):

def flatten_list(list1):
    out = []
    inside = list1
    while inside:
        x = inside.pop(0)
        if isinstance(x, list):
            inside = x + inside
        else:
            out.append(x)
    return out

out = [flatten_list(sublist) for sublist in list1]

flatten_list([['milk', ['bread', ['eggs']]]]) #['milk', 'bread', 'eggs']

还有一个(这次使用递归生成器函数):

list1 = [
    ['milk', 'bread', 'eggs'], 
    ['eggs', ['milk'], 'bread'], 
    [[['eggs']], 'milk', [['bread']]]
]

def flatten(lst):
    for item in lst:
        if isinstance(item, list):
            yield from flatten(item)
        else:
            yield item

list2 = [list(flatten(sublist)) for sublist in list1]
print(list2)

这将产生

[['milk', 'bread', 'eggs'], ['eggs', 'milk', 'bread'], ['eggs', 'milk', 'bread']]

递归函数可能是处理此问题的最简单方法:

def flatten(L):
    return [f for v in L for f in flatten(v)] if isinstance(L,list) else [L]


list1=[['milk', 'bread', 'eggs'], ['eggs', ['milk'], 'bread']]
print(flatten(list1))
['milk', 'bread', 'eggs', 'eggs', 'milk', 'bread']

您也可以使用迭代方法(在本例中就地进行):

def flatten(L):
    for i,_ in enumerate(L):
        while isinstance(L[i],list):
            L[i:i+1] = L[i]

list1=[['milk', 'bread', 'eggs'], ['eggs', ['milk'], 'bread']]
flatten(list1)
print(list1)
['milk', 'bread', 'eggs', 'eggs', 'milk', 'bread']

在for循环中使用enumerate()是为了随着列表的增长不断获取额外的索引