从里到外迭代嵌套列表

het*_*sch 2 python python-3.x

我有以下python嵌套列表结构:

test = ['a', ['c', ['e'], 'd'], 'b']
Run Code Online (Sandbox Code Playgroud)

或者相同,只是格式化:

test = [
    'a', 
        [
            'c', 
                [
                    'e'
                ], 
             'd'
        ], 
    'b'
]
Run Code Online (Sandbox Code Playgroud)

我想知道迭代完整列表的最佳方法是什么,从最里面的嵌套列表对象('e')到最外面的列表('a',[...],'b')以相反的顺序开始.对反向(测试)的调用只是没有嵌套列表的技巧.它应该能够在迭代的每个深度上调用回调函数.

迭代应该看起来像这样([xx] ==来自先前调用的回调的计算值):

1st e --> callback(e)
2nd c [e] d --> callback(c [e] d)
3rd a [c e d] b --> callback(a [c e d] b)
Run Code Online (Sandbox Code Playgroud)

希望这能解释我的问题并感谢您的帮助

Abh*_*jit 6

我建议的一个可能的解决方案是

>>> def foo(test):
    queue = []
    try:
        while True:
            queue.append(test)
            test = test[1]
    except IndexError:
        for e in reversed(queue):
            yield e


>>> data = foo(test)
>>> next(data)
['e']
>>> next(data)
['c', ['e'], 'd']
>>> next(data)
['a', ['c', ['e'], 'd'], 'b']
>>> next(data)

Traceback (most recent call last):
  File "<pyshell#753>", line 1, in <module>
    next(data)
StopIteration
>>> 
Run Code Online (Sandbox Code Playgroud)

这个怎么运作

  1. 遍历深度优先,并推送队列中的元素
  2. 循环反转队列并生成元素


nne*_*neo 6

您正在寻找的是结构的后序遍历:

def traverse(l):
    for x in l:
        if isinstance(x, list):
            traverse(x)
    callback(l)
Run Code Online (Sandbox Code Playgroud)

如果callback定义为print,我们得到

['e']
['c', ['e'], 'd']
['a', ['c', ['e'], 'd'], 'b']
Run Code Online (Sandbox Code Playgroud)

  • 谢谢,这看起来比@Abhijit回答简单. (2认同)
  • @Lattyware:`isinstance(x,list)`可以很容易地改为`isinstance(x,collections.Iterable)`,在任何情况下,用户的例子只处理列表. (2认同)