8

この回答に基づいて、次のように別のクラスの一部として1 行のツリーを作成したいと思います。

self._tree = collections.defaultdict(lambda: self._tree)

上記のクラスのユーザーがパス要素をツリーに追加し、最下位のツリー レベルからコールバックを実行できるようにする必要があります。私の単純な実装では、実行時にエラーが発生しますpytest:

def _add(self, tree, path):
    for node in path:
        tree = tree[node]

def _run(self, tree, callback):
    for key in tree.keys():
        callback(tree[key]) # !!! Recursion detected (same locals & position)
        self._run(key)

このコードは、ツリーが次のように定義されている場合に機能します。

    def tree():
        return collections.defaultdict(tree)

    self._tree = tree()

私の素朴なアプローチがラムダ式で機能しないのはなぜですか?


Python の禅では、

シンプルは複雑よりも優れています。

1 行のラムダは、より単純な実装がある場合にコードを複雑にします。したがって、1 行のラムダは製品コードでは使用しないでください。ただし、この質問は学術的な関心のためにここに残しておきます。

4

2 に答える 2

7

最初のリンクされた質問の1行のdefaultdictデザインは、私には正しく見えません。異常な自己参照ループが生成されます。

>>> d = collections.defaultdict(lambda: d)
>>> d["a"] = 23
>>> d["b"]["c"] = 42
>>> print d["b"]["a"] #we never created a value with these keys, so it should just return a defaultdict instance.
23
>>> #uh, that's not right...

2 番目のリンクの関数の 1 行のラムダ実装は、次のようになります。

tree = lambda: defaultdict(tree); self._tree = tree()


編集:次のように単一のステートメントで実行できるように見えます:

self._tree = (lambda f: f(f))(lambda t: defaultdict(lambda: t(t)))

... しかし、スクリプトを 1 つのステートメントだけ縮小するためだけに、大学レベルのラムダ計算のスキルを要求するのは賢明ではありません。よりわかりやすいアプローチを検討してください。

于 2016-03-02T16:12:24.897 に答える