在练习列表和字典时,我尝试了以下代码,但不了解其输出。你能解释一下吗?
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位。
如果您能告诉我输出之间差异的原因,那就太好了。
谢谢!
答案 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
变量x
和y
指向同一列表对象。我可以通过执行
x is y # True
如果我愿意
x.append("foo")
y.append("bar")
print "x:", x
print "y:", y
输出为:
x: ["foo", "bar"]
y: ["foo", "bar"]
因为x
和y
指向同一列表。
代码中也会发生同样的事情。
当您执行list1.append(json1)
时,json1
指向一个字典,并且其值永不变(您永不执行json1 = ...
),因此结果是同一字典两次被追加到列表中,并且对该字典所做的更改将反映在两个列表元素中。
要获得预期的结果,您需要复制json1
的字典并将副本附加到列表中。将行list1.append(json1)
替换为list1.append(dict(json1))
将为您带来预期的结果,因为dict()
创建了该词典的副本。