2020-11-28

Unexpected behavior when appending to a Dict[str, list] - values are appended to all lists [duplicate]

I am iterating through a list and trying to appended values to a Dict[str, list] called plot. I look up the str-type key (real_key) to the appropriate list in plot and then I append a value (value) to that list.

some = x['string']

for od in some:
    conversion_key = od.get("@alias")
    real_key = field_conversion[conversion_key]
    value = od.get("#text")
    print(f"\nconversion_key: {conversion_key}\nreal_key: {real_key}\nvalue: {value}")
    # unexpected behavior from line below
    plot[real_key].append(value)
    pprint(plot)

As you can see, each value gets appended to all the lists in the dict, not just the list that is accessed by real_key. Why does this happen?

conversion_key: TemplateResRef
real_key: TemplateResRef
value: cod_bks_lite_tombs_1
{'PlotFlagEndsPlot': ['cod_bks_lite_tombs_1'],
 'PlotFlagJournal': ['cod_bks_lite_tombs_1'],
 'PlotFlagMultiReward': ['cod_bks_lite_tombs_1'],
 'PlotFlagReward': ['cod_bks_lite_tombs_1'],
 'PlotGUID': ['cod_bks_lite_tombs_1'],
 'PlotGUID2': ['cod_bks_lite_tombs_1'],
 'PlotName': ['cod_bks_lite_tombs_1'],
 'PlotParentGUID': ['cod_bks_lite_tombs_1'],
 'PlotScript': ['cod_bks_lite_tombs_1'],
 'TemplateResRef': ['cod_bks_lite_tombs_1']}

conversion_key: PlotFlags
real_key: PlotGUID
value: F400FDC4F9B24A5890F664E2966A7410
{'PlotFlagEndsPlot': ['cod_bks_lite_tombs_1',
                      'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotFlagJournal': ['cod_bks_lite_tombs_1',
                     'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotFlagMultiReward': ['cod_bks_lite_tombs_1',
                         'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotFlagReward': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotGUID': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotGUID2': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotName': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotParentGUID': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410'],
 'PlotScript': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410'],
 'TemplateResRef': ['cod_bks_lite_tombs_1', 'F400FDC4F9B24A5890F664E2966A7410']}

For reference, the initial empty dict of lists (called plot) and the conversion dict (field_conversion) that translates between keys is below:

field_conversion = {
    "PlotFlags": "PlotGUID",
    "PlotFlagID": "PlotName",
    "PlotFlagName": "PlotScript",
    "PlotFlagReward": "PlotFlagReward",
    "PlotFlagJournal": "PlotFlagJournal",
    "PlotName": "PlotParentGUID",
    "PlotFlagMultiReward": "PlotFlagMultiReward",
    "PlotFlagEndsPlot": "PlotFlagEndsPlot",
    "PlotGUID": "PlotGUID2",
    "TemplateResRef": "TemplateResRef"
}

plot = dict.fromkeys(list(field_conversion.values()), [])
plot
{'PlotGUID': [],
 'PlotName': [],
 'PlotScript': [],
 'PlotFlagReward': [],
 'PlotFlagJournal': [],
 'PlotParentGUID': [],
 'PlotFlagMultiReward': [],
 'PlotFlagEndsPlot': [],
 'PlotGUID2': [],
 'TemplateResRef': []}

EDIT/SOLUTION:

Maybe it's better to delete this post, but when I implemented my dic, plot this way:

plot = dict.fromkeys(list(field_conversion.values()), [])

All its values point to the same [] held in memory. So updating one key updates all the lists, because the lists are all the same object.

Implementing the dict this way fixed it.

for val in field_conversion.values():
    plot[val] = []


from Recent Questions - Stack Overflow https://ift.tt/3lfm6ML
https://ift.tt/eA8V8J

No comments:

Post a Comment