Why the nested dictionary cannot append into list correctly?

Viewed 39

I try to append a dictionary into a list, but I find the sub-dictionary is always keep the last one I read from CSV file(deviceProfile.csv). Does anyone know why? Here is my CSV file.

name,description,primaryTable,startingAddress,boolIndex
test_name_1,1,table_1,1,1
test_name_2,2,table_2,2,2
test_name_3,3,table_3,3,3

Here is my python code.

import csv
import yaml
from pprint import pprint

resource = {
    'name': "",
    'description': "",
    'attributes':
      { 'primaryTable': "", 'startingAddress': "", 'boolIndex': "" },
}

resourceArray = []

with open("deviceProfile.csv") as f:
    myCsvDic = csv.DictReader(f)
    for row in myCsvDic:
        resource['name'] = row['name']
        resource['description'] = row['description']
        resource['attributes']['primaryTable'] = row['primaryTable']
        resource['attributes']['startingAddress'] = row['startingAddress']
        resource['attributes']['boolIndex'] = row['boolIndex']
        test = resource.copy()
        resourceArray.append(test)

pprint (resourceArray)

And the result is

[{'attributes': {'boolIndex': '3',
                 'primaryTable': 'table_3',
                 'startingAddress': '3'},
  'description': '1',
  'name': 'test_name_1'},
 {'attributes': {'boolIndex': '3',
                 'primaryTable': 'table_3',
                 'startingAddress': '3'},
  'description': '2',
  'name': 'test_name_2'},
 {'attributes': {'boolIndex': '3',
                 'primaryTable': 'table_3',
                 'startingAddress': '3'},
  'description': '3',
  'name': 'test_name_3'}]

It is strange that name and description are appended into list correctly, but attributes. The attributes is always append the last sub-dictionary.

Any help will be appreciated. Thanks.

2 Answers

This is because of copy. by default copy is shallow copy and it will copy just level-1 elements. you should use deepcopy in your case. replace test = resource.copy() with:

from copy import deepcopy

test = deepcopy(resource)

take a look at this Link for more information, or any other links that tells you about copy(shallow and deep).

Why do you have resource on the top outside the loop ???

resource = {
    'name': "",
    'description': "",
    'attributes':
      { 'primaryTable': "", 'startingAddress': "", 'boolIndex': "" },
}

Remove that and just change the loop to this :

for row in myCsvDic:
    resource = {}
    resource['name'] = row['name']
    resource['description'] = row['description']
    resource['attributes']['primaryTable'] = row['primaryTable']
    resource['attributes']['startingAddress'] = row['startingAddress']
    resource['attributes']['boolIndex'] = row['boolIndex']
    resourceArray.append(resource)
Related