0

I was trying to implement a shortest path algorithm in python. I ran into some trouble when I attempted to connect my points on the path.

I have a class called NODE I made an array of these nodes and then created new nodes in them like this:

nodes = []
for r in range ( 0, 3 ):
 for c in range ( 0, 3 ):
 nodes.append( NODE( c*WIDTH/20 + 30, r*HEIGHT/20 + 30, 10 ) )

This created nodes, which is fine, I can draw them just fine.
At first I attempted connecting them by adding a list of node objects into the the NODE class. I ran into some issues, I thought the problem is with the recursive classes, so to test I did this.
Where connections is a blank array within the NODE class.

nodes[0].connections.append( 0 )
print nodes[0].connections
nodes[1].connections.append( 1 )
print nodes[1].connections
print nodes[0].connections

This is where I found the problem, Maybe I'm just being stupid, or It's a language thing ? Dunno, but I thought I'd ask.

The output is this:
[ 0 ]
[ 0, 1 ]
[ 0, 1 ]

As you can see, I only added 1 object to the connections list in the index 1. However when I print the contents, I see two.... And this confuses me.

asked Jun 6, 2017 at 18:26
6
  • 1
    This is really hard to answer without seeing a minimal reproducible example that includes the actual NODE class. Commented Jun 6, 2017 at 18:27
  • 2
    Let me guess, class Node has a static field connections instead of initializing connections in the constructor to a new list, so that all objects share a single connection list? Show your Node class, please. Commented Jun 6, 2017 at 18:29
  • 1
    I'm going to go ahead and say this is a duplicate of The mutable default argument. Commented Jun 6, 2017 at 18:30
  • yep. Thats the problem. I was writing it as though I would write something in Java or cpp. Thanks for the help guys ! Commented Jun 6, 2017 at 19:28
  • Which one is the problem? A static property or a mutable default argument? Commented Jun 6, 2017 at 20:00

1 Answer 1

3

Possibilty 1: your code looks like this:

class NODE:
 connections = []
 def __init__(self, value):
 self.value = value
nodes = [NODE(23), NODE(42)]
nodes[0].connections.append( 0 )
print nodes[0].connections
nodes[1].connections.append( 1 )
print nodes[1].connections
print nodes[0].connections

Solution: class instance attributes should be defined inside __init__. If you define connections at the class level, then every single instance of NODE will share the same one connections list.

class NODE:
 def __init__(self, value):
 self.value = value
 self.connections = []

Possibility 2: your code looks like this:

class NODE:
 def __init__(self, value, connections = []):
 self.value = value
 self.connections = connections
nodes = [NODE(23), NODE(42)]
nodes[0].connections.append( 0 )
print nodes[0].connections
nodes[1].connections.append( 1 )
print nodes[1].connections
print nodes[0].connections

Solution: the default value in an argument list is created only once, so all instances of NODE using that default value will share the same one list. use a non-mutable sentinel value to indicate that no argument was passed. None is usually suitable for this task.

class NODE:
 def __init__(self, value, connections = None):
 self.value = value
 if connections is not None:
 self.connections = connections
 else:
 self.connections = []
answered Jun 6, 2017 at 18:37
Sign up to request clarification or add additional context in comments.

1 Comment

yea this is it. Thanks for answering ! This is gonna fix a lot of my other problems too !

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.