谁能解释以下代码的输出?

时间:2019-07-09 16:04:47

标签: python python-2.7

在练习列表和字典时,我尝试了以下代码,但不了解其输出。你能解释一下吗?

list1 = []
json1 = {
    "key1": "",
    "key2": ""
}
json1['key2'] = 'value2'
list2 = ["list_item_1", "list_item2"]
for item in list2:
    json1['key1'] = item
    list1.append(json1)
print list1

我得到的输出是:

[{'key2': 'value2', 'key1': 'list_item2'}, {'key2': 'value2', 'key1': 'list_item2'}]

据我了解,输出应为

[{'key2': 'value2', 'key1': 'list_item1'}, {'key2': 'value2', 'key1': 'list_item2'}]

[{'key2': 'value2', 'key1': 'list_item2'}, {'key2': 'value2', 'key1': 'list_item1'}]

我的理解在某处是错误的,但是我想知道什么是错误的。 我在Windows 10平台上使用 python 2.7.13 64位。

如果您能告诉我输出之间差异的原因,那就太好了。

谢谢!

3 个答案:

答案 0 :(得分:0)

这样做的时候

list1.append(json1)

您要将对象json1附加到list1。在该循环的下一个迭代中,您更改json1,然后再次将其 附加到list1。请注意,您已经两次将相同的对象添加到循环中,只是在两者之间更改了该对象的属性。

因此,当您打印列表时,它将打印同一对象两次。为了避免这种情况的发生,您需要将json1单独但相同的副本添加到list1中(以便以后修改原始列表时,而不修改您已经添加到列表中的副本)。您可以使用dict.copy()方法进行此操作:

for item in list2:
    json1['key1'] = item
    list1.append(json1.copy())

答案 1 :(得分:0)

我怀疑您的误解是来自此行:

list1.append(json1)

这会将 object json1附加到list;您似乎希望它能对json1的当前值进行快照,然后将该 copy 放入list1中。如果您想要这种效果,请使用

list1.append(copy(json1))

但是,这只会复制json1的顶层;如果字典包含对象,则需要先import copy,然后再使用copy.deepcopy(json1)

这有助于清除您的理解,还是使其变得更加复杂?

答案 2 :(得分:0)

问题是您不了解变量如何在python中工作。在python中,一切是一个对象,所有变量都是指向值的指针。这意味着当您这样做

x = []
y = x

变量xy指向同一列表对象。我可以通过执行

来验证
x is y  # True

如果我愿意

x.append("foo")
y.append("bar")
print "x:", x
print "y:", y

输出为:

x: ["foo", "bar"]
y: ["foo", "bar"]

因为xy指向同一列表。

代码中也会发生同样的事情。
当您执行list1.append(json1)时,json1指向一个字典,并且其值永不变(您永不执行json1 = ...),因此结果是同一字典两次被追加到列表中,并且对该字典所做的更改将反映在两个列表元素中。

要获得预期的结果,您需要复制json1的字典并将副本附加到列表中。将行list1.append(json1)替换为list1.append(dict(json1))将为您带来预期的结果,因为dict()创建了该词典的副本。