I am using the snippet from this answer, more specifically the one that uses a lambda
.
I have been trying to implement this using the :=
operator in Python 3.8 and I ended up with two different implementations, both of which I believe does what I want.
Snippet 1 (using a lambda defined beforehand, same as snippet in linked answer)
from collections import defaultdict
from pprint import pprint
func = lambda:defaultdict(func)
infinite_nested_dicts_one = func()
infinite_nested_dicts_one[1][2][3][4][5]['a'] = '12345a'
infinite_nested_dicts_one[1][2][3][4][5]['b'] = '12345b'
print(infinite_nested_dicts_one[1][2][3][4][5]['a']) # '12345a'
print(infinite_nested_dicts_one[1][2][3][4][5]['b']) # '12345b'
pprint(infinite_nested_dicts_one)
Output 1
12345a
12345b
defaultdict(<function <lambda> at 0x000001A7405EA790>,
{1: defaultdict(<function <lambda> at 0x000001A7405EA790>,
{2: defaultdict(<function <lambda> at 0x000001A7405EA790>,
{3: defaultdict(<function <lambda> at 0x000001A7405EA790>,
{4: defaultdict(<function <lambda> at 0x000001A7405EA790>,
{5: defaultdict(<function <lambda> at 0x000001A7405EA790>,
{'a': '12345a',
'b': '12345b'})})})})})})
Snippet 2 (using assignment operator)
from collections import defaultdict
from pprint import pprint
infinite_nested_dicts_two = (func:=defaultdict(lambda:func))
infinite_nested_dicts_two[1][2][3][4][5]['a'] = '12345a'
infinite_nested_dicts_two[1][2][3][4][5]['b'] = '12345b'
print(infinite_nested_dicts_two[1][2][3][4][5]['a']) # '12345a'
print(infinite_nested_dicts_two[1][2][3][4][5]['b']) # '12345b'
pprint(infinite_nested_dicts_two)
Output 2
12345a
12345b
defaultdict(<function <lambda> at 0x0000022F1A0EA790>,
{1: <Recursion on defaultdict with id=2401323545280>,
2: <Recursion on defaultdict with id=2401323545280>,
3: <Recursion on defaultdict with id=2401323545280>,
4: <Recursion on defaultdict with id=2401323545280>,
5: <Recursion on defaultdict with id=2401323545280>,
'a': '12345a',
'b': '12345b'})
In both cases accessing the outer most defaultdict
for [1][2][3][4][5]['a']
and [1][2][3][4][5]['b']
gives me the same output.
So the question is
pprint
output different?defaultdict
of defaultdict
?PS :
I am aware the the syntactical equivalent using :=
is infinite_nested_dicts_two = (func:=lambda:defaultdict(func))()
.
Do let me know if any clarification is needed. Many Thanks.
Your second version assigns a defaultdict
instance to func
(and, redundantly, to infinite_nested_dicts_two
). Accordingly, instead of using func
(which is not a function!) as its default-generating function, it uses a constant function that always returns func
—i.e., the dictionary itself is the default value. The necessary result is the heavily recursive structure revealed by pprint
, since every level of indexing adds a key to, and returns, the same object.