Как создать tree+defaultdict произвольного уровня вложенности?

В Python есть известная фича:
def tree():
	return defaultdict(tree)
Хочу усложнить это дерево, чтобы можно было задавать ограниченное число уровней вложенности, и последний заканчивался бы указанной мной функцией:
def tree2(levels=0, func=None):
	pass
Например, выражение
d = tree2(levels=2, func=int)
должно давать:
d = defaultdict(lambda: defaultdict(int))
d['key1']['key2'] += 5
Как это можно грамотно реализовать? Пока смотрю в сторону reduce().
  • Вопрос задан
  • 2638 просмотров
Решения вопроса 1
adugin
@adugin Автор вопроса, куратор тега Python
Родил такое решение:
def tree(levels=0, func=None):
	if levels > 0 and func:
		return defaultdict(reduce(lambda f, i: lambda: defaultdict(f), xrange(levels-1), func))
	else:
		return defaultdict(tree)


Проверяем:
>>> d = tree()
>>> d[1][2][3][4][5] = 6
>>> d = tree(3, float)
>>> d
defaultdict(<function <lambda> at 0x0280E3F0>, {})
>>> d[1][2][3]
0.0
>>> d[7][8][9] += 10
>>> d[7][8][9]
10.0


P.S. https://gist.github.com/hrldcpr/2012250

P.P.S. Ещё вариант:
def tree(func=lambda: tree(), depth=0):
	return defaultdict(reduce(lambda f, i: lambda: defaultdict(f), xrange(depth-1), func))
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
yttrium
@yttrium
>>> def tree(func=None, level=-1):
...     if not func:
...         func = tree
...     if not level:
...         return func()
...     return defaultdict(lambda : tree(func, level-1))
...
>>> f = tree()
>>> f
defaultdict(<function <lambda> at 0x2b00e978>, {})
>>> f[3]
defaultdict(<function <lambda> at 0x2b00eb28>, {})
>>> f[1][2][3][4]
defaultdict(<function <lambda> at 0x2b00ec48>, {})
>>> f = tree(float, 3)
>>> f[1]
defaultdict(<function <lambda> at 0x2b00eb28>, {})
>>> f[1][2]
defaultdict(<function <lambda> at 0x2b00ec00>, {})
>>> f[1][2][3]
0.0
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы
Level Travel Москва
До 160 000 ₽
Big Data Solutions Санкт-Петербург
от 100 000 до 220 000 ₽
19 февр. 2020, в 04:53
2000 руб./за проект
19 февр. 2020, в 02:24
500 руб./за проект
18 февр. 2020, в 23:53
8000 руб./за проект