可変オブジェクトの再帰関数

2020-02-18 python python-3.x recursion

クラスですべてのパスを再帰的に構築しようとしています。ここに私がこれまでに持っているものがあります:

def get_paths(self, component=None, current_path=None, all_paths=None):

    # set defaults
    if component is None: 
        component = self._ground; 
        current_path = [component,]

    ##### [START] RECURSIVE PART #####

    # get parents of component
    parents = component.parents()

    # if no parents (an endpoint/leaf), add the current_path
    if not parents:
        all_paths.append(current_path)

    # if parents ==> recurse
    # note: because we're starting from the ground and getting all parents
    # we insert the parent before the current path (not after, like if we
    # were recursively getting files in a directory)
    else:
        for parent in parents:
            self.get_paths(parent, [parent,] + current_path), all_paths)

    ##### [END] RECURSIVE PART #####

    # Note that the recursion doesn't 'return' anything, it only modifies
    # the list. We still have to return the list by the method at the end.      
    return all_paths

これは、「グラウンド」から始まり、要素に親がなくなるまで再帰します。私の質問は、これが再帰を実行する一般的な方法であるかどうかです-実際には「再帰部分」に何かを返すのではなく、変更可能な要素(ここのリスト)を変更して、後で結果を返すだけです。

上記が理想的でない場合、それをどのように改善できるかの例は何ですか?または、パスのリストを返す他の方法は何ですか(上記は$ find ./がパスのリストを取得する方法と非常に似ています)。

Answers

それを行う簡単な方法は、プライベートな再帰メソッドを呼び出すパブリックの「インターフェース」メソッドを用意することです。

これらの線に沿った何か:

class Klass:

    _ground = 'ground'

    # Public method.
    def get_paths(self, component=None, current_path=None):
        all_paths = []
        self._get_paths(all_paths, component, current_path)  # Call private method.
        return all_paths

    # Private method.
    def _get_paths(self, all_paths, component=None, current_path=None):
        # Modifies all_paths - executed for that side-effect.    

        # set defaults
        if component is None:
            component = self._ground;
            current_path = [component,]

        # get parents of component
        parents = component.parents()

        # if no parents (an endpoint/leaf), add the current_path
        if not parents:
            all_paths.append(current_path)
        else:
            for parent in parents:
                self._get_paths(parent, [parent,] + current_path), all_paths)

Related