提问人:compski 提问时间:7/5/2013 最后编辑:Ashwini Chaudharycompski 更新时间:5/8/2022 访问量:105279
如何在Python中将嵌套列表转换为一维列表?[复制]
How to convert a nested list into a one-dimensional list in Python? [duplicate]
问:
我尝试了所有方法(据我所知),从拆分数组并将它们连接在一起 甚至使用 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 部分?
答:
您需要递归循环列表并检查项目是否可迭代(字符串也是可迭代的,但跳过它们)。
itertools.chain
将不起作用,因为它要求它的所有项都是可迭代的,但 和 (整数) 是不可迭代的。这就是为什么它适用于第二个,因为它是一个列表列表。[1,[2,2,2],4]
1
4
>>> 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']
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]
实际上,在不使用 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]
如果它只是列表列表的一个级别,那么最简单的解决方案是:
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)) 是因为即使您的项目中有一个集合,也不会造成任何问题。这将处理字符串、整数、布尔值、字典、列表以及元组等项目。
如果您正在使用,则可以执行以下操作: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)
你可能想看看这里:http://caolanmcmahon.com/posts/flatten_for_python/ http://rightfootin.blogspot.de/2006/09/more-on-python-flatten.html
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']
使用递归将多嵌套列表转换为单个切片列表。
要在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]
from nltk import flatten
example_list = [1, [2, 3], 3]
flattened_list = flatten(example_list)
print(flattened_list)
输出:[1、2、3、3]
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]
使用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']
此 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]
您不必使用 .只需使用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]
使用管道包
from pipe import chain
lst=[[1,2], [3,4], [5,6]]
list(lst|chain)
[1, 2, 3, 4, 5, 6]
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]
评论