遍历嵌套列表的列表

4
我有一个嵌套的列表,它以以下形式出现:
 A = [[a,b],[c,d]] or [[[a,b],[c,d]]] or [[[[a,b],[c,d]]]] or [[[[[a,b],[c,d]]]]] 

等等。这些形式的A不会同时出现。

无论A嵌套多深,我该如何编写代码来剥离列表,并仅获取:

[a,b] 
[c,d]

我尝试了这个:
def Peel_list(Features):
    try:
        for lon,lat in Features:
            print((lon,lat))
    except:
        for Feature in Features:
            for t_list in Feature:
                for A in t_list:
                    for lon,lat in A:
                        print((lon,lat))
    return()

但它只适用于有限的A。

你可以展开列表,然后构建你的最终结果。 - Devesh Kumar Singh
1
你能保证始终将列表作为内部元素吗?不会像[[[a], b, [c, d]]]这样吗? - OneCricketeer
可能不是一个答案……您能像这个例子一样展平列表吗:https://dev59.com/qnNA5IYBdhLWcg3wdtld#952946,然后从生成的简单列表中提取[lon,lat]数据作为数字对?(提取连续的数字对a,b,然后c,d,然后e,f等) - Stidgeon
5个回答

4

通常,当我们想要处理任意嵌套对象的问题时,递归是一个很好的开始。在这里,我们希望不断“向下挖掘”,直到达到基本情况,即任何非列表值。代码大致如下

test = [1, [3,4],[[5]], [[[6]]]]
peeled = []

def peel(myList, peeled):
    for val in myList:
        if isinstance(val, list):
            if not isinstance(val[0], list):
                peeled.append(val)
            else:
                peel(val, peeled)
        else:
            peeled.append(val)


peel(test, peeled)
print(peeled)

这将为您提供类似以下的结果:

[1, [3, 4], [5], [6]]


非常感谢。我真的很感激。 - Anthony Ifeanyi

3

对于你提供的情况,一个简单的方法是使用while循环,不断检查列表的大小是否为1,并修改你的列表以只包含单个元素(这将摆脱最外层的列表)。

x = [[[[[a,b],[c,d]]]]]
while len(x) == 1:
    x = x[0]

// result is x = [[1, 2], [3, 4]]

当您有任意嵌套列表的元素时,一般的解决方法是使用Mitchel的答案。

使用测试用例 [1, [3,4],[[5]], [[[6]]]] 对我来说无法工作。 - Mitch
1
实际上,仔细读了一遍后,我认为我把这个问题搞得比 OP 想象的更复杂了。这应该适用于他的情况。 - Mitch
1
这将无法处理类似于 [[[[[1]]]]] 这样的内容。 - Mitch
非常感谢。我真的很感激。 - Anthony Ifeanyi

0

你也可以尝试在列表上使用numpy ravel函数,输出将是一个一维数组。


非常感谢。我真的很感激。 - Anthony Ifeanyi
结果是否符合您的要求?因为最终使用ravel()会得到一个1D数组,而不是保持内层数组结构的2D数组。 - Desmond

0

这里是另一种基于递归的解决方案:

l1 = [[[['a','b'],['c','d'], [[1,2]]]]]
l2 = [[[[['a','b'],['c','d']]]]]

def f(inp):
    # you can skip this if statement if you are sure that there is no empty nested list 
    if not inp:
        return [[]]
    if (all(isinstance(element, list) for element in inp)):
        return [elem for x in inp for elem in f(x)]
    else:
        return [inp]

all()可以检查可迭代对象中的每个元素是否符合条件。
结果将是:

f(l1) #[['a', 'b'], ['c', 'd'], [1, 2]]
f(l2) #[['a', 'b'], ['c', 'd'], []]

非常感谢。我真的很感激。 - Anthony Ifeanyi

0

你可以在生成器中使用递归:

def flatten(d):
   if all(not isinstance(i, list) for i in d):
      yield d
   else:
      for i in d:
         yield from flatten(i)

print(list(flatten([[[[['a', 'b'], ['c', 'd']]]]])))

输出:

[['a', 'b'], ['c', 'd']]

非常感谢。我真的很感激。 - Anthony Ifeanyi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接