Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

One line tree implementation

Based of this answer, I want to create a one line tree as part of another class like thus:

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

I will need to allow the users of said class to add path elements to the tree and run some callback starting at the lowest tree level. My naive implementation raises a error when I run 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)

This code works iff the tree is defined as

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

    self._tree = tree()

Why is my naive approach not working with the lambda expression?


⚠ The Zen of Python states that

Simple is better than complex.

The one-line lambda makes the code complex where there is a simpler implementation. Therefore the one-line lambda should not be used in production code. However, I shall leave this question here for academic interest.

like image 685
Sardathrion - against SE abuse Avatar asked Mar 02 '16 16:03

Sardathrion - against SE abuse


1 Answers

The one-line defaultdict design in the first linked question doesn't look right to me. It produces unusual self-referential loops:

>>> 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...

A one-line lambda implementation of the function in your second link would look more like:

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


Edit: looks like you can do it in a single statement with:

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

... But requiring college-level lambda calculus skills just to shrink your script by one statement seems like an unwise bargain. Consider a more understandable approach.

like image 195
Kevin Avatar answered Oct 04 '22 03:10

Kevin