这是我的Python代码,它创建了一个无限嵌套的字典:
a = a['k'] = {}
print(a)
print(a['k'])
print(a['k']['k'])
print(a is a['k'])
以下是输出:
{'k': {...}}
{'k': {...}}
{'k': {...}}
True
输出显示a['k']
引用a
本身,从而使其无限嵌套。
我猜这句话:
a = a['k'] = {}
表现如下:
new = {}
a = new
a['k'] = new
这确实会创建一个无限嵌套的字典。
我查看了 Python语言参考的Section 7.2: Assignment statements,但找不到任何暗示a = a['k'] = {}
应该首先将a
设置为新字典的内容然后在该字典中插入一个键/值对。以下是我发现相关但未回答我问题的参考摘录:
如果目标列表是没有尾随逗号的单个目标,则可以选择将其分配给该目标。
如果目标是预订:评估引用中的主表达式。它应该产生可变的序列对象(例如列表)或映射对象(例如字典)。接下来,计算下标表达式。
如果主要对象是映射对象(例如字典),则下标必须具有与该映射的键类型兼容的类型,然后要求该映射创建一个键/基准对,该键/数据对将下标映射到所分配的宾语。可以用相同的键值替换现有的键/值对,也可以插入新的键/值对(如果不存在具有相同值的键)。
这些摘录中的每一个都定义了具有单个目标(例如a = {}
和a['k'] = {}
)的作业的行为,但是它们似乎并没有讨论在a = a['k'] = {}
的情况下应该发生的情况。 。这种陈述的评估顺序在哪里记录?
答案 0 :(得分:4)
根据the section 7.2 you quoted(强调我的观点),从左到右解决分配声明中的分配:
赋值语句评估表达式列表(请记住, 这可以是单个表达式或逗号分隔的列表,后者 产生一个元组),并将单个结果对象分配给每个对象 目标列表,从左到右。
这意味着,确实,您的陈述等同于:
new = {}
a = new
a['k'] = new
作为快速的反证明,交换分配顺序会导致错误:
a['k'] = a = {}
提高
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined