如何在不改变形状的情况下取消(取消)不必要的嵌套列表?(Python)
这与我在许多线程中发现的情况大不相同-我并不是要将列表平铺,而是要将最不重要的级别如下所示:如何在不改变形状的情况下取消(取消)不必要的嵌套列表?(Python),python,nested-lists,Python,Nested Lists,这与我在许多线程中发现的情况大不相同-我并不是要将列表平铺,而是要将最不重要的级别如下所示: [[3,3]]应该是[3,3] [[3,4],[3,3]]]应该是[[3,4],[3,3]],而不是[3,4],[3,3]或[3,4,3,3],因为这完全改变了结构 基本上,我希望在循环中断之前的第一次和第二次迭代中降低级别以获得相同的len(a_list)。但我的想法有些错误: 此代码适用于除[[3]、[4]]以外的任何内容。不知道今天出了什么问题,因为它昨天起作用了。需要一些帮助来更正此功能。现在它
[[3,3]]
应该是[3,3]
[[3,4],[3,3]]]
应该是[[3,4],[3,3]]
,而不是[3,4],[3,3]
或[3,4,3,3]
,因为这完全改变了结构
基本上,我希望在循环中断之前的第一次和第二次迭代中降低级别以获得相同的len(a_list)
。但我的想法有些错误:
此代码适用于除[[3]、[4]]
以外的任何内容。不知道今天出了什么问题,因为它昨天起作用了。需要一些帮助来更正此功能。现在它返回[3],但应该保持不变
# Unlevel list - reduce unnecessary nesting without changing nested lists structure
def unlevelList(l):
if len(l) > 0 and isinstance(l, list):
done = True
while done == True:
if isinstance(l[0], list):
if len(l) == len(l[0]):
l = l[0]
else:
l = l[0]
done = False
else:
done = False
return l
else:
return l
我倾向于使用递归来实现这一点:如果对象是长度为1的列表,则去掉外层;然后,递归地取消其所有子级的级别
def unlevel(obj):
while isinstance(obj, list) and len(obj) == 1:
obj = obj[0]
if isinstance(obj, list):
return [unlevel(item) for item in obj]
else:
return obj
test_cases = [
[[[3, 3]]],
[[[3, 4], [3, 3]]],
[[3], [4]],
[[[3]]],
[[[3], [3, 3]]]
]
for x in test_cases:
print("When {} is unleveled, it becomes {}".format(x, unlevel(x)))
结果:
When [[[3, 3]]] is unleveled, it becomes [3, 3]
When [[[3, 4], [3, 3]]] is unleveled, it becomes [[3, 4], [3, 3]]
When [[3], [4]] is unleveled, it becomes [3, 4]
When [[[3]]] is unleveled, it becomes 3
When [[[3], [3, 3]]] is unleveled, it becomes [3, [3, 3]]
When [[[3, 3]]] is unleveled, it becomes [3, 3]
When [[[3, 4], [3, 3]]] is unleveled, it becomes [[3, 4], [3, 3]]
When [[3], [4]] is unleveled, it becomes [[3], [4]]
When [[[3]]] is unleveled, it becomes 3
When [[[3], [3, 3]]] is unleveled, it becomes [[3], [3, 3]]
编辑:再次阅读您的问题,我想您可能希望
[[3],[4]]
保持[[3],[4]]
。如果是这样的话,那么我将需求解释为“仅从顶层剥离多余的括号;保留内部的一个元素列表不受影响”。在这种情况下,您不需要递归。只需去掉最上面的列表,直到你不能再做了,然后把它还给我
def unlevel(obj):
while isinstance(obj, list) and len(obj) == 1:
obj = obj[0]
return obj
test_cases = [
[[[3, 3]]],
[[[3, 4], [3, 3]]],
[[3], [4]],
[[[3]]],
[[[3], [3, 3]]]
]
for x in test_cases:
print("When {} is unleveled, it becomes {}".format(x, unlevel(x)))
结果:
When [[[3, 3]]] is unleveled, it becomes [3, 3]
When [[[3, 4], [3, 3]]] is unleveled, it becomes [[3, 4], [3, 3]]
When [[3], [4]] is unleveled, it becomes [3, 4]
When [[[3]]] is unleveled, it becomes 3
When [[[3], [3, 3]]] is unleveled, it becomes [3, [3, 3]]
When [[[3, 3]]] is unleveled, it becomes [3, 3]
When [[[3, 4], [3, 3]]] is unleveled, it becomes [[3, 4], [3, 3]]
When [[3], [4]] is unleveled, it becomes [[3], [4]]
When [[[3]]] is unleveled, it becomes 3
When [[[3], [3, 3]]] is unleveled, it becomes [[3], [3, 3]]
我也推荐一个递归解决方案
def unnest(l):
if isinstance(l, list) and len(l) == 1 and isinstance(l[0], list):
return unnest(l[0])
return l
一些测试用例
test_cases = [
[[[3], [3, 3]]],
[[[3, 3]]],
[[[3, 4], [3, 3]]],
[[3], [4]],
[[[3]]]
]
for i in test_cases:
print(unnest(i))
给予
[[3], [3, 3]]
[3, 3]
[[3, 4], [3, 3]]
[[3], [4]]
[3]
这段代码似乎正是您想要的。将列表保持为列表(但平铺)
结果
res
是[[1,2]、[2,3,4,5]、[134,56]、9,8,0]
我相信如果子列表的大小不同,即如果数据结构不是矩形,您的实现就会遇到问题。这会错误地将[[3]、[3,3]]]
升级到[3,3]
,我相信[[3] ,[3,3]]
。@blhsing我想你是对的。我添加了一个额外的方法。老实说还不错。这个“多余的括号”正是我想要的。谢谢两个版本。这已经完成了,但我不能更改[[[[[4]]]]
来始终获得一个列表。因此,我想改为4
想要[4]
.Hmm,也许您可以将最后一行更改为如果是instance(obj,list)则返回obj,否则[obj]
。Nathan的回答还确保结果是一个list。这与我想要的不完全一样(不是取出内部嵌套),但它也很有用。