【问题标题】:Recursively searching an object and editing a string when found递归搜索对象并在找到时编辑字符串
【发布时间】:2016-07-26 11:54:51
【问题描述】:

我是 python 新手,在处理不可变字符串时遇到了问题。我的问题如下:

我有一棵树,其中每个节点都是一个字典,每个节点都有可变数量的子节点。我希望在这棵树上执行多个操作,因此递归遍历它。

设置是我有一个类,它使用以下函数遍历树:

def __recursiveDive(self, node, enterFunc, leaveFunc, parentNode):
    if self.__break:
        return

    if not self.__skipNode:
        enterFunc(node, parentNode, self)
        if isinstance(node, dict):
            for key, value in node.items():
                self.__recursiveDive(value, enterFunc, leaveFunc, node)
        elif isinstance(node, list):
            for child in node:
                if isinstance(child, dict):
                    self.__recursiveDive(child, enterFunc, leaveFunc, node)

        leaveFunc(node, parentNode, self)
    else:
        self.__skipNode = False

enterFunc 和 leaveFunc 在外部定义并在树/节点上执行所需的工作。

我的问题是,由于 python 字符串是不可变的,我觉得我无法修改树中的任何字符串字段。 enterFunc 是属于另一个类的函数,传递给该类如下:

def enter(self, node, parentNode, traverser):
    if isinstance(node, str):
        search = re.search(self.regexPattern, node)
        if search:
            node = node.replace(search.group(2),self.modifyString(search.group(2)))

此处对节点的更改仅是本地的。让输入和离开函数返回节点是我唯一的解决方案吗?

解决此问题的正确/pythonic 方法是什么?

对于那些想要 TL;DR 解决方案的人

确保您的模式返回已完成工作的变量。

【问题讨论】:

    标签: python string design-patterns recursion immutability


    【解决方案1】:

    您的enterFuncleaveFunc 应该返回修改后的对象,而不是尝试就地修改它。那么__recursiveDive函数就可以用返回的对象替换原来的对象了。

    通常你会以这样一种方式实现__recursiveDive,它知道 both 节点的键和值,但在你的代码中似乎并非如此 -它传递了一个node 变量,但没有传递相应的键。它应该像这样工作(显然是伪代码):

    def __recursiveDive(self, enter, leave):
        for key, value in self.nodes:
            new_value= enter(value)
            self.nodes[key]= new_value
    
            if isinstance(new_value, dict):
                new_value.__recursiveDive(enter, leave)
    
            new_value= leave(new_value)
            self.nodes[key]= new_value
    

    【讨论】:

    • 感谢您的回复。快速提问:“new_value.__recursiveDive(enter, leave)”字典 new_value 没有成员函数 __recursirveDive。我想我的问题是,作为 new_value 的合法性与 __recursiveDive 所属的类型不同。
    • @John 将类型检查视为一种if __recursiveDive should be called on this object: call __recursiveDive。我不确定如何用你的代码来实现它。
    • 好的,谢谢,这更有意义!为了清楚起见,数据结构非常糟糕(不幸的是,我无法控制)。每个叶子/节点可以是列表或字典,它们是嵌套的,有时是它的字典->字典....或列表元素->字典->列表->元素->字典->字典等等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-23
    相关资源
    最近更新 更多