我有一个包含5个词典的列表,当我更新dictionary[0]
时,它还会同时更新dictionary[4]
。奇怪的是它不是系统的,字典似乎对我来说是独立的,尽管它们共享相同的内容。
程序1显示我遇到的问题。
程序2显示了使用deepcopy
解决方法,但我觉得它不那么聪明。
我想:
提前感谢任何反馈。
程序1和程序2更新列表outputDictL
中的词典。使用refLists
中的数据执行更新。 outputDictL[0]
是一个字典,其中包含来自数据的键值。 outputDict[4]
是一个字典,其中包含一个字典,其键值在我们的示例中与outputDict[0]
相同。
计划1和计划2几乎相同。不同之处在于,在程序2中,我使用字典的深层副本作为函数参数,而不是它的引用。
#!/usr/bin/python
# -*- coding: ISO-8859-15 -*-
# Id: $
L1 = " "
import copy
##A dds one qTime item to a dictionary
# dates is an array
def addQTime2dict(dictionary, key, dates):
#"%s k %s, v: %s"%(L6, key, value)
print "%s adding key : %s dates : %s"%(L1, key, dates)
if key in dictionary :
dictionary[key].extend(dates)
else :
dictionary.update({key : dates})
## updates all dictionaries
def updateDicts(outputDictL, S, D, fqdn, dates):
print "--- fqdn : %s, dates : %s"%(fqdn, dates)
print "- Before updating Dict[0]\n%s outputDictL : %s"%(L1, outputDictL)
addQTime2dict(outputDictL[0], fqdn, dates)
print "- After updating Dict[0]\n%s outputDictL : %s"%(L1, outputDictL)
if D not in outputDictL[4] :
outputDictL[4][D] = {}
print "- Before updating Dict[4]\n%s outputDictL : %s"%(L1, outputDictL)
addQTime2dict(outputDictL[4][D], fqdn, dates)
print "- After updating Dict[4]\n%s outputDictL : %s"%(L1, outputDictL)
outputDictL = map( lambda x : {} , range(5))
refList = [("S1", "D1", "f1", "data1"), ("S2", "D1", "f1", "data2")]
for l in refList :
print "-------------------"
updateDicts(outputDictL, l[0], l[1], l[2], [l[3]])
print "-------------------\n"
-------------------
--- fqdn : f1, dates : ['data1']
- Before updating Dict[0]
outputDictL : [{}, {}, {}, {}, {}]
adding key : f1 dates : ['data1']
- After updating Dict[0]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {}]
- Before updating Dict[4]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {'D1': {}}]
adding key : f1 dates : ['data1']
- After updating Dict[4]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {'D1': {'f1': ['data1']}}]
-------------------
这正如我们所料。 f1,data1正确放置在outputDictL[0]
和outputDictL[4]
-------------------
--- fqdn : f1, dates : ['data2']
- Before updating Dict[0]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {'D1': {'f1': ['data1']}}]
adding key : f1 dates : ['data2']
- After updating Dict[0]
outputDictL : [{'f1': ['data1', 'data2']}, {}, {}, {}, {'D1': {'f1': ['data1', 'data2']}}]
- Before updating Dict[4]
outputDictL : [{'f1': ['data1', 'data2']}, {}, {}, {}, {'D1': {'f1': ['data1', 'data2']}}]
adding key : f1 dates : ['data2']
- After updating Dict[4]
outputDictL : [{'f1': ['data1', 'data2', 'data2']}, {}, {}, {}, {'D1': {'f1': ['data1', 'data2', 'data2']}}]
-------------------
这不是我们的预期:每次更新这些词典时,f1:data2已插入outputDictL[0]
和outputDictL[4]
。要查看我们的期望,您可以查看Program2输出。
#!/usr/bin/python
# -*- coding: ISO-8859-15 -*-
# Id: $
L1 = " "
import copy
##A dds one qTime item to a dictionary
# dates is an array
def addQTime2dict(dictionary, key, dates):
#"%s k %s, v: %s"%(L6, key, value)
print "%s adding key : %s dates : %s"%(L1, key, dates)
if key in dictionary :
dictionary[key].extend(dates)
else :
dictionary.update({key : dates})
return dictionary
## updates all dictionaries
def updateDicts(outputDictL, S, D, fqdn, dates):
print "--- fqdn : %s, dates : %s"%(fqdn, dates)
print "- Before updating Dict[0]\n%s outputDictL : %s"%(L1, outputDictL)
outputDictL[0] = addQTime2dict(copy.deepcopy(outputDictL[0]), fqdn, dates)
print "- After updating Dict[0]\n%s outputDictL : %s"%(L1, outputDictL)
if D not in outputDictL[4] :
outputDictL[4][D] = {}
print "- Before updating Dict[4]\n%s outputDictL : %s"%(L1, outputDictL)
outputDictL[4][D] = addQTime2dict(copy.deepcopy(outputDictL[4][D]), fqdn, dates)
print "- After updating Dict[4]\n%s outputDictL : %s"%(L1, outputDictL)
outputDictL = map( lambda x : {} , range(5))
refList = [("S1", "D1", "f1", "data1"), ("S2", "D1", "f1", "data2")]
for l in refList :
print "-------------------"
updateDicts(outputDictL, l[0], l[1], l[2], [l[3]])
print "-------------------\n"
-------------------
--- fqdn : f1, dates : ['data1']
- Before updating Dict[0]
outputDictL : [{}, {}, {}, {}, {}]
adding key : f1 dates : ['data1']
- After updating Dict[0]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {}]
- Before updating Dict[4]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {'D1': {}}]
adding key : f1 dates : ['data1']
- After updating Dict[4]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {'D1': {'f1': ['data1']}}]
-------------------
-------------------
--- fqdn : f1, dates : ['data2']
- Before updating Dict[0]
outputDictL : [{'f1': ['data1']}, {}, {}, {}, {'D1': {'f1': ['data1']}}]
adding key : f1 dates : ['data2']
- After updating Dict[0]
outputDictL : [{'f1': ['data1', 'data2']}, {}, {}, {}, {'D1': {'f1': ['data1']}}]
- Before updating Dict[4]
outputDictL : [{'f1': ['data1', 'data2']}, {}, {}, {}, {'D1': {'f1': ['data1']}}]
adding key : f1 dates : ['data2']
- After updating Dict[4]
outputDictL : [{'f1': ['data1', 'data2']}, {}, {}, {}, {'D1': {'f1': ['data1', 'data2']}}]
-------------------
f1:data2只在每个字典中插入一次。这就是我们想要的。
答案 0 :(得分:1)
两个词典中的值都是相同的,因为python只存储对象的引用。将列表分配给两个不同词典中的值时,实际存储在这些词典中的是对同一列表的引用。因此,您实际上只创建了一个列表,只使用两个词典中的引用来修改单个列表。您可以在以下简单示例中看到此行为:
>>> l1 = []
>>> l2 = l1
>>> l2.append('item')
>>> l1
['item']
>>> l2
['item']
变量l1和l2都指向相同的实际列表。使用deepcopy
产生期望结果的原因是它创建了一个全新的列表,其中填充了与原始列表相同的值。
关于addQTime2dict
功能的一个额外注意事项:因为您在致电key
时已确认dictionary
不在update
,因此效果相同使用更简单的dictionary[key] = dates
答案 1 :(得分:1)
您正在共享两个dicts之间的日期列表的引用。将列表添加到字典时,您应该制作副本以防止此共享
def addQTime2dict(dictionary, key, dates):
#"%s k %s, v: %s"%(L6, key, value)
print "%s adding key : %s dates : %s"%(L1, key, dates)
if key in dictionary:
dictionary[key].extend(dates)
else:
dictionary[key] = dates[:] # copy of dates
答案 2 :(得分:0)
这是相当多的代码,但我认为dict.has_key()方法可以解决您的问题。例如,在您的第一个列表中:
def addQTime2dict(dictionary, key, dates):
#"%s k %s, v: %s"%(L6, key, value)
print "%s adding key : %s dates : %s"%(L1, key, dates)
if dictionary.has_key(key):
dictionary[key].extend(dates)
else :
dictionary.update({key : dates})