1

When I generate a dict, and add it to a list, then generate a second dict with similar structure and append it to that list, the resulting list is two copies of the second dict, as opposed to a list containing both the first and second dicts.

My code:

    i=1
    UnitTabs = {};   TextUnits=[]
    theseTextUnits = {}
    theseTextUnits['documentId'] = i
    theseTextUnits['xPosition'] = 200; theseTextUnits['yPosition'] = 200;  theseTextUnits['name'] = 'From date'
    TextUnits.append(theseTextUnits)
    theseTextUnits['xPosition'] = 250; theseTextUnits['yPosition'] = 250;   theseTextUnits['name'] = 'To date'
    TextUnits.append(theseTextUnits)
    print(TextUnits)

Expected output:

[{'xPosition': 200, 'yPosition': 200, 'name': 'From date', 'documentId': 1},
 {'xPosition': 250, 'yPosition': 250, 'name': 'To date', 'documentId': 1}]

Actual output:

[{'xPosition': 250, 'yPosition': 250, 'name': 'To date', 'documentId': 1}, 
 {'xPosition': 250, 'yPosition': 250, 'name': 'To date', 'documentId': 1}]
Suzanne
  • 582
  • 2
  • 11
  • 31
  • You didn't generate a second dictionary; you changed the values in a single dictionary. Add another `theseTextUnits = {}` before you start assigning the econd set of values to actually create a second dictionary. Or, just use dictionary literals to define all the fields at once (and generate new dictionaries). – kindall Feb 12 '18 at 04:33
  • Shouldn't the key/value pairs of what gets sent the list be frozen, such that later updating of the dictionary doesn't change what's already present in the list? – Suzanne Feb 12 '18 at 04:35
  • @Suzanne No, what you put into your list is a reference of the dictionary instead of actual values. – Yunkai Xiao Feb 12 '18 at 04:39
  • 1
    @Suzanne no, that is not how it will work. Generally, in Python data is never implicitly copied. The list contains references to dictionary objects, if you modify those objects, those changes will be visible in the list. – juanpa.arrivillaga Feb 12 '18 at 04:40
  • 1
    @Suzanne check out this blog post by a Stackoverflow legend that addresses many common stumbling block about how Python variables and objects work: https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Feb 12 '18 at 04:45

3 Answers3

1

It is happening because you are modifying the same dict instance:

theseTextUnits['name'] = 'To date'

And, this will change the value in the original dict as well. What you need to do is copy the dict and then modify the values you want to.

import copy
newDict = copy.deepcopy(theseTextUnits)
newDict['xPosition'] = 250
newDict['yPosition'] = 250
newDict['name'] = 'To date'
TextUnits.append(newDict)
AKS
  • 18,983
  • 3
  • 43
  • 54
0

What's happening here is that you are editing the same dictionary. Python never implicitly copies objects. If you use the copy method it will fix the issue

TextUnits.append(theseTextUnits.copy())

usernamenotfound
  • 1,540
  • 2
  • 11
  • 18
0

Dictionaries in Python are mutable objects. This means that the actual value can be changed (as opposed to returning a new object)

For instance:

a={1:1}
b=a
b[1]=2
print(a)

{1:2}
Stephen C
  • 1,966
  • 1
  • 16
  • 30