1

I'm trying to make a node class with a name and a dict of its neighbors, along with the tag by which it refers to this neighbor (not necessarily the neighbor's name).

class node:
def __init__(self,name='',neighbors={}):
    self.name=name
    self.neighbors=neighbors

def addNeighbor(self,neighborTag,neighbor):
    if neighborTag not in self.neighbors.keys():
        self.neighbors[neighborTag] = neighbor

However when I perform the following:

foo = node(name='foo')
foo.addNeighbor('fooneighbor',node(name='bar'))

The dict entry {'fooneighbor',node object} also appears in foo.neighbors['fooneighbor'].neighbors (which I expected to be blank).

I'm guessing this is something to do with how dicts work that I'm not aware of. Can anyone enlighten me?

gorio
  • 35
  • 1
  • 5

1 Answers1

0

Quoting from the docs,

Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function, e.g.:

def whats_on_the_telly(penguin=None):
    if penguin is None:
        penguin = []
    penguin.append("property of the zoo")
    return penguin

So, you can fix your problem, like this

def __init__(self,name='',neighbors=None):
    self.name=name
    if neighbors == None:
       neighbors = dict() 
    self.neighbors=neighbors
thefourtheye
  • 233,700
  • 52
  • 457
  • 497