在迭代python列表时修改元素时这种行为背后的原因是什么

Yas*_*pta 2 python dictionary list python-3.x

在下面的代码中,第一种类型的修改改变了原始列表,而在第二个列表中保持不变。为什么行为是这样?

temp = [{"a":"b"},{"c":"d"},{"e":"f"},{"a":"c"}]

for item in temp:
    if "a" in item:
        item["a"] = "x"
print(temp)
Run Code Online (Sandbox Code Playgroud)
temp = [{"a":"b"},{"c":"d"},{"e":"f"},{"a":"c"}]

for item in temp:
    item  = {}
print(temp)
Run Code Online (Sandbox Code Playgroud)

第一个的输出是 [{'a': 'x'}, {'c': 'd'}, {'e': 'f'}, {'a': 'x'}]

第二个是 [{'a': 'b'}, {'c': 'd'}, {'e': 'f'}, {'a': 'c'}]

Python 版本是 3.6.5

Dee*_*ace 6

for item in temp:
    item  = {}
Run Code Online (Sandbox Code Playgroud)

在每次迭代中,列表元素item都被丢弃,取而代之的是一个新的局部变量(碰巧也被调用item)被创建并分配了一个空的 dict,而后者也被丢弃。原始列表完全不受影响。

这可以用 可视化id,它返回对象的内存地址:

temp = [{}]
for item in temp:
    print(id(item))
    item = {}
    print(id(item))
Run Code Online (Sandbox Code Playgroud)

输出

2704138237016
2704138237816
Run Code Online (Sandbox Code Playgroud)

请注意我们如何获得 2 个不同的 ID。1 表示列表中的 dict,另一个表示循环内创建的新 dict。


相比

for item in temp:
    if "a" in item:
        item["a"] = "x"
Run Code Online (Sandbox Code Playgroud)

hereitem永远不会被其他东西重新分配(没有行说item = ...),所以item总是指向原始列表中的 dict 。您正在分配给该'a'原始item字典的键。