简体   繁体   English

访问嵌套列表和dicts中的所有元素,无需递归

[英]visit all elements in nested lists and dicts without recursion

I have a structure consisting of nested lists and dicts. 我有一个由嵌套列表和dicts组成的结构。 I want to apply a function to every element. 我想将函数应用于每个元素。 How to do it without recursion. 怎么做没有递归。

def visit(data, func):
    if isinstance(data, dict):
        for k, v in data.items():
            data[k] = visit(v, func)
        return data
    elif isinstance(data, list):
        for i, v in enumerate(data):
            data[i] = visit(v, func)
        return data
    else:
        return func(data)

The recursive version works for small data, but I hit the RecursionError exception when the data is big. 递归版本适用于小数据,但是当数据很大时我遇到了RecursionError异常。

I looked for general ways to eliminate recursion, the ones I found rely on first transforming the recursive call to a tail call, my problem with this is the recursive call in my example is inside a loop. 我寻找消除递归的一般方法,我发现依赖于首先将递归调用转换为尾调用,我的问题是我的例子中的递归调用是在循环内部。

This approach will work. 这种方法会起作用。 For the record, though, I agree with Sven Marnach that there is something definitely fishy going on with your data structures if you have nesting that is breaking the recursion limit. 但是,对于记录,我同意Sven Marnach的说法,如果您的嵌套符合递归限制,那么您的数据结构肯定会出现问题。 If as Sven conjectures,you have cycles in your data, this approach will also break. 如果像Sven推测的那样,你的数据中有循环,这种方法也会破裂。

data = [1,2, {'a':1, 'b':{'a':[1,2,3]}},3]

def apply(data, f):
    stack = []
    stack.append(data)
    while stack:
        data = stack.pop()
        if isinstance(data, dict):
            for k,v in data.items():
                if isinstance(v, (dict,list)):
                    stack.append(v)
                else:
                    data[k] = f(v)
        if isinstance(data, list):
            for i,e in enumerate(data):
                if isinstance(e, (dict,list)):
                    stack.append(e)
                else:
                    data[i] = f(e)

In the interpreter shell: 在解释器shell中:

$ python -i apply.py
>>> apply(data, lambda x: x + 1)
>>> data
[2, 3, {'a': 2, 'b': {'a': [2, 3, 4]}}, 4]
>>> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM