[英]Why does this Python snippet regarding dictionaries work?
说我们有这个
>>> x = {'a': 1, 'b': 2}
>>> y = {}
>>> for k, y[k] in x.items(): pass
...
>>> y
{'a': 1, 'b': 2}
为什么这样做?
注意:我首先 在这里看到这个
a, b = (c, d)
从左到右解包元组并按顺序分配a = c
和b = d
。
x.items()
迭代x
的键值对。 例如,做list(x.items())
会得到[('a', 1), ('b', 2)]
for a, b in x.items()
将键分配给a
,并将x
每个键值对的值分配给b
。
for k, y[k] in x.items()
将键分配给k
,并将x
每个键值对的值分配给y[k]
。
您可以在y[k]
使用k
,因为k
已经被分配,因为解包发生在左右
你不需要在循环中做任何事情,因为你需要的任何东西都已经完成了。
因为循环已经将x
每个值都分配给y[k]
,所以y
现在是x
的浅拷贝。
正如您引用的推文所说,这确实是执行x.copy()
的“简洁、不直观且令人困惑”的方式
这是使用循环绑定的一种非常奇怪的方式。 对于每个项目, (key, value)
的元组被分配到k, y[k]
。 k
两个实例都引用同一个变量,因此订阅y[k]
分配到字典y
。 这依赖于从左到右解决的解构赋值; 使用y[k], k
不起作用,因为在循环中第一次没有分配k
。
迭代变量在迭代可迭代对象时被赋值。 在您的情况下, k, y[k]
从dict.items()
分配有(key, value)
dict.items()
。
在你的情况下y[k]
实际上在这里调用dict.__setitem__
这就是为什么你的y
得到更新。
例子,
class T():
def __setitem__(self, key, value):
print(f"Assigning {key} with value {value}")
x = {"a": 2, "b": 3, "c": 4}
val = T()
for k, val[k] in x.items():
pass
Assigning a with value 2
Assigning b with value 3
Assigning c with value 4
在您的情况下, dict.__setitem__
在迭代x.items()
被调用, dict.__setitem__
改变您的 dict y
因此最终您将x
dict 复制到y
。
x = {'a': 2, 'b': 3, 'c': 4} it = iter(x.items()) y = {} [*iter(lambda : y.__setitem__(*next(it)), "Is this confusing enough??")] print(y) # {'a': 2, 'b': 3, 'c': 4}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.