如何取消嵌套(取消级别)不必要的嵌套列表而不改变其形状? (蟒蛇)

时间:2019-02-15 19:04:47

标签: 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]]以外的任何内容。邓诺(Dunno)今天有什么问题,因为它昨天才起作用。需要一些帮助来更正此功能。现在它返回[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

3 个答案:

答案 0 :(得分:6)

我倾向于递归地执行此操作:如果对象是长度为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]]

编辑:再次阅读您的问题,我想您可能希望[[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]]

答案 1 :(得分:2)

我也推荐一个递归解决方案

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]

答案 2 :(得分:1)

此代码似乎完全符合您的要求。保持列表为列表(但保持不变)。

import itertools

a = [[[[1, 2]]], [[2, 3, 4, 5]], [[[[[[134, 56]]]]]], 9, 8, 0]
res = []

for element in a:
  if isinstance(element, list):
    while len(element) == 1:
      element = list(itertools.chain(*element))
    res.append(element)
  else:
    res.append(element)

print(res)

结果res[[1, 2], [2, 3, 4, 5], [134, 56], 9, 8, 0]