Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python append dictionary to list

According to this post, I need to use .copy() on a dictionary, if I want to reference a dictionary which gets updated in a loop (instead of always referencing the same dictionary). However, in my code example below this doesn't seem to work:

main.py:

import collections
import json

nodes_list = ['donald', 'daisy', 'mickey', 'minnie']
edges_list = [('donald', 'daisy', '3'), ('mickey', 'minnie', '3'), ('daisy', 'minnie', '2')]
node_dict, edge_dict = collections.defaultdict(dict), collections.defaultdict(dict)
ultimate_list = []


for n in nodes_list:
    node_dict["data"]["id"] = str(n)
    ultimate_list.append(node_dict.copy())

for e in edges_list:
    edge_dict["data"]["id"] = str(e[2])
    edge_dict["data"]["source"] = e[0]
    edge_dict["data"]["target"] = e[1]
    ultimate_list.append(edge_dict.copy())

print(json.dumps(ultimate_list, indent=2))

As a result here I get the following:

[
  {
    "data": {
      "id": "minnie"
    }
  },
  {
    "data": {
      "id": "minnie"
    }
  },
  {
    "data": {
      "id": "minnie"
    }
  },
  {
    "data": {
      "id": "minnie"
    }
  },
  {
    "data": {
      "target": "minnie",
      "id": "2",
      "source": "daysi"
    }
  },
  {
    "data": {
      "target": "minnie",
      "id": "2",
      "source": "daysi"
    }
  },
  {
    "data": {
      "target": "minnie",
      "id": "2",
      "source": "daysi"
    }
  }
]

Whereas I would actually expect to get this:

[
  {
    "data": {
      "id": "donald"
    }
  },
  {
    "data": {
      "id": "daisy"
    }
  },
  {
    "data": {
      "id": "mickey"
    }
  },
  {
    "data": {
      "id": "minnie"
    }
  },
  {
    "data": {
      "target": "donald",
      "id": "3",
      "source": "daysi"
    }
  },
  {
    "data": {
      "target": "mickey",
      "id": "3",
      "source": "minnie"
    }
  },
  {
    "data": {
      "target": "minnie",
      "id": "2",
      "source": "daysi"
    }
  }
]

Can anyone please tell me what I'm doing wrong here?

like image 592
dliv Avatar asked Dec 02 '25 23:12

dliv


2 Answers

dict.copy only makes a shallow copy of the dict, the nested dictionaries are never copied, you need deep copies to have those copied over too.

However, you can simply define each new dict at each iteration of the loop and append the new dict at that iteration instead:

for n in nodes_list:
    node_dict = collections.defaultdict(dict) # create new instance of data structure
    node_dict["data"]["id"] = str(n)
    ultimate_list.append(node_dict)

Same applies to the edge_dict:

for e in edges_list:
    edge_dict = collections.defaultdict(dict)
    ...
    ultimate_list.append(edge_dict)
like image 118
Moses Koledoye Avatar answered Dec 05 '25 12:12

Moses Koledoye


Use copy.deepcopy(your_dict): deepcopy.

like image 23
Anton Hulikau Avatar answered Dec 05 '25 11:12

Anton Hulikau



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!