Python中defaultdict的任意嵌套defaultdict的以下两个实现有什么区别?
What is the difference between the following two implementaions of an arbitrary nested defaultdict of defaultdict in Python?
我正在使用 this answer 中的代码片段,更具体地说,是使用 lambda
.
的代码片段
我一直在尝试使用 Python 3.8 中的 :=
运算符来实现这一点,最后我得到了两种不同的实现方式,我相信这两种实现方式都符合我的要求。
片段 1(使用预先定义的 lambda,与链接答案中的片段相同)
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)
输出 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'})})})})})})
片段 2(使用赋值运算符)
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)
输出 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'})
在这两种情况下,为 [1][2][3][4][5]['a']
和 [1][2][3][4][5]['b']
访问最外层的 defaultdict
会得到相同的输出。
所以问题是
- 为什么
pprint
输出不同?
- 这些是否相同?
- 它们都是
defaultdict
的任意嵌套 defaultdict
吗?
- 我是不是漏掉了一些细节?
PS :
我知道使用 :=
的语法等价物是 infinite_nested_dicts_two = (func:=lambda:defaultdict(func))()
.
如果需要任何说明,请告诉我。非常感谢。
您的第二个版本将 defaultdict
实例 分配给 func
(并且冗余地分配给 infinite_nested_dicts_two
)。因此,它没有使用 func
(这不是函数!)作为其默认生成函数,而是使用始终 returns func
— 即 ,字典本身是默认值。必然的结果是由 pprint
揭示的高度递归结构,因为每个索引级别都会添加一个键,并且 returns,相同的 object.
我正在使用 this answer 中的代码片段,更具体地说,是使用 lambda
.
我一直在尝试使用 Python 3.8 中的 :=
运算符来实现这一点,最后我得到了两种不同的实现方式,我相信这两种实现方式都符合我的要求。
片段 1(使用预先定义的 lambda,与链接答案中的片段相同)
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)
输出 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'})})})})})})
片段 2(使用赋值运算符)
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)
输出 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'})
在这两种情况下,为 [1][2][3][4][5]['a']
和 [1][2][3][4][5]['b']
访问最外层的 defaultdict
会得到相同的输出。
所以问题是
- 为什么
pprint
输出不同? - 这些是否相同?
- 它们都是
defaultdict
的任意嵌套defaultdict
吗? - 我是不是漏掉了一些细节?
PS :
我知道使用 :=
的语法等价物是 infinite_nested_dicts_two = (func:=lambda:defaultdict(func))()
.
如果需要任何说明,请告诉我。非常感谢。
您的第二个版本将 defaultdict
实例 分配给 func
(并且冗余地分配给 infinite_nested_dicts_two
)。因此,它没有使用 func
(这不是函数!)作为其默认生成函数,而是使用始终 returns func
— 即 ,字典本身是默认值。必然的结果是由 pprint
揭示的高度递归结构,因为每个索引级别都会添加一个键,并且 returns,相同的 object.