У меня есть список из 5 словарей, и когда я обновляю dictionary[0]
, он также одновременно обновляет dictionary[4]
.Странно то, что он не является систематическим, и словари кажутся мне независимыми, хотя они имеют одно и то же содержание.
Программа 1 показывает проблему так, как я с ней столкнулся.
Программа 2 показываетспособ обойти с помощью deepcopy
, но я чувствую, что это не так умно.
Я хотел бы:
- Понять причины, почему Программа 1 не работает так, как нужноЯ ожидаю
- Есть ли лучший (умнее, эффективнее) способ написания Программы 2.
Заранее благодарен за любую обратную связь.
Программа 1 иПрограмма 2 обновляет словари в списке outputDictL
.Обновления выполняются с данными, найденными в refLists
.outputDictL[0]
- это словарь, который имеет ключевые значения из данных.outputDict[4]
- это словарь, содержащий словарь, значения ключей которого в нашем примере такие же, как outputDict[0]
.
Программа 1 и Программа 2, и почти одинаковые.Разница в том, что в программе 2 я использую глубокую копию словаря для аргумента функции, а не ее ссылку.
Программа 1
Исходный код программы 1:
#!/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"
Вывод программы 1:
-------------------
--- 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, данные1 правильно размещены в 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: данные2 были вставлены как в outputDictL[0]
, так и в outputDictL[4]
каждый раз, когда эти словарибыли обновлены.Чтобы увидеть, что мы ожидаем, вы можете проверить выход Program2.
Program 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})
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"
Выход Program2:
-------------------
--- 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: данные2 были вставлены только один раз в каждый словарь.Это то, что мы хотели.