views:

156

answers:

2

Newbie Alert:

I'm new to Python and when I'm basically adding values to a dict, I find that when I'm printing the whole dictionary, I get the same value of something for all keys of a specific key.

Seems like a pointer issue?

Here's a snippet when using the event-based XML parser (SAX):

Basically with every end element of "row", I'm storing the element by it's key: self.Id, where self is the element.

def endElement(self, name):
  if name == "row":
   self.mapping[self.Id] = self
   print "Storing...: " + self.DisplayName + " at Id: " + self.Id
+4  A: 

You'll get the value self for every single entry in self.mapping, of course, since that's the only value you ever store there. Did you rather mean to take a copy/snapshot of self or some of its attributes at that point, then have self change before it gets stored again...?

Edit: as the OP has clarified (in comments) that they do indeed need to take a copy:

import copy

...

    self.mapping[self.Id] = copy.copy(self)

or, use copy.deepcopy(self) if self has, among its attributes, dictionaries, lists etc that need to be recursively copied (that would of course include self.mapping, leading to rather peculiar results -- if the normal, shallow copy.copy is not sufficient, it's probably worth adding the special method to self's class to customize deep copying, to avoid the explosion of copies of copies of copies of ... that would normally result;-).

Alex Martelli
I'm using a sax parser, so endElement is called whenever the end of an element is reached... I'm trying to store the element at its Id
LB
Alex, thanks, yes that's what I meant. How would I assign a "copy" instead a "reference" ?
LB
`import copy` and store `copy.copy(self)` (or `copy.deepcopy(self)` if you need recursive copies of all containers you have as attributes: lists, dicts, etc).
Alex Martelli
+2  A: 

If I understand what you're saying, then this is probably expected behaviour. When you make an assignment in Python, you're just assigning the reference (sort of like a pointer). When you do:

self.mapping[self.Id] = self

then future changes to self will be reflected in the value for that mapping you just did. Python does not "copy" objects (unless you specifically write code to do so), it only assigns references.

Greg Hewgill
Ah exactly what I had thought, thanks!
LB
If you do want to copy the value, check out the copy module
zdav