-1

I have a class called Station...

class Station():
    def __init__(self):
        self.connecting_stations = []

...a list with 3 Station instances...

stations = [Station() for n in range(3)]

...and a for-loop that appends the string "New Hampshire" to the connecting_stations attribute of my three Station instances.

for station in stations:
    station.connecting_stations.append("New Hampshire")

When I print([station.connecting_stations for station in stations]) it prints:

[
["New Hampshire", "New Hampshire", "New Hampshire"],
["New Hampshire", "New Hampshire", "New Hampshire"],
["New Hampshire", "New Hampshire", "New Hampshire"]
]

...i.e. the connecting_stations attribute of all of my Station instances have the same "New Hampshire" repeated 3 times.

But what I really wanted to do is:

>>> print(stations[0].connecting_stations)
["New Hampshire"]
>>> print(stations[1].connecting_stations)
["New Hampshire"]
>>> print(stations[2].connecting_stations)
["New Hampshire"]

...i.e. I want each one of my Station instances to have one -- only one -- connecting station, which is called "New Hampshire", but actually they're getting 3 "New Hampshire" strings each.

How is that even possible? What is happening and how can I solve my problem?

Actual full code:

import random
import turtle


class Game():

    def __init__(self, difficulty):
        number_of_stations = {
            "easy": 3,
            "medium": 5,
            "hard": 8
            }
        turtle.setworldcoordinates(0, -500, 500, 0)
        self.max_x = 500
        self.min_y = -500
        self.stations = self.create_stations(number_of_stations[difficulty])
        self.create_connections()

    def create_stations(self, number_of_stations):
        available_colors = [
            "#0A2463", "#3E92CC", "#C200FB", "#D8315B", "#1E1B18",
            "#564138", "#EEC643", "#F46036"
            ]
        available_xs = list(range(int(self.max_x*0.1), int(self.max_x*0.9)+1))
        available_ys = list(range(int(self.min_y*0.9), int(self.min_y*0.1)+1))
        stations = []
        # Adding stations (random color and random pos)
        for n in range(number_of_stations):
            station_color = available_colors.pop(random.randint(0, len(
                available_colors)-1))
            station_x = available_xs.pop(
                random.randint(0, len(available_xs)-1))
            station_y = available_ys.pop(
                random.randint(0, len(available_ys)-1))
            for x in range(station_x-int(self.max_x*0.05),
                           station_x+int(self.max_x*0.05)):
                if x in available_xs:
                    available_xs.remove(x)
            for y in range(station_y+int(self.min_y*0.05),
                           station_y-int(self.min_y*0.05)):
                if y in available_ys:
                    available_ys.remove(y)
            stations.append(Station(n, station_color, (station_x, station_y)))
        return stations

    def create_connections(self):
        for station in self.stations:
            station.connecting_stations.append("New Hampshire")


class Station():

    def __init__(self, identification,
                 color, position, connecting_stations=[]):
        self.id = identification
        self.color = color
        self.position = position
        self.x = self.position[0]
        self.y = self.position[1]
        self.connecting_stations = connecting_stations
        self.number_of_connections = len(self.connecting_stations)

        # Station's turtle instance setup
        self.turtle_instance = turtle.Turtle()
        self.turtle_instance.color(self.color)
        self.turtle_instance.speed("fastest")


game1 = Game("hard")

for station in game1.stations:
    print(station.id, station.connecting_stations)

Note: Sorry for the bad title. Did not find better and shorter words to describe my problem.

santosmarco_
  • 121
  • 2
  • No, it really doesn't. Literally copy-paste your code, it does work the way you want. I bet the code you're having problems with is different. I even bet I know how it's different: `[Station()] * 3`, right? – John Zwinck Jul 29 '18 at 03:03
  • Are you *sure* the code you've shown is what you're running? Double check that you've saved the latest version and you're running it, not an older version. The issue you describe could be caused by either the `Station` instances or the list within them being references to the same object, but the code you've shown wouldn't cause that to happen. – Blckknght Jul 29 '18 at 03:16
  • @JohnZwinck I've just edited the question with the full code. I thought it would be very big for a question, so I tried to simplify my problem. Seems like I could not replicate it very well. Can you still try to help me out? – santosmarco_ Jul 29 '18 at 03:36
  • @Blckknght I've just put my entire code on the question above. Can you try again with my full code? It will not run as I was expecting. – santosmarco_ Jul 29 '18 at 03:37
  • 1
    @santosmarco_: Looks like the issue is the fact that the list in the `Station` constructor comes from a default argument. That's always going to use the same list object. Check out the answers in the duplicate question and you'll find how you can fix the issue. – Blckknght Jul 29 '18 at 04:03

1 Answers1

0

Seems like you're not adding 3 different instances of your class to the list, but the same instance, and then when you modify it 3 times, you get "New Hapmshire" added to this same instance 3 times.

Try to replace:

for station in stations:
    station.connecting_stations.append("New Hampshire")

with

stations[0].connecting_stations.append("New Hampshire")

and print your list again to see =)

lenik
  • 23,228
  • 4
  • 34
  • 43
  • I am sure they're not the same. I simplified the program for that question, but actually the `Station` instance have more attributes, like color, position etc. that differentiates one from the others. – santosmarco_ Jul 29 '18 at 03:20
  • I edited the question with my full code. Can you try again? – santosmarco_ Jul 29 '18 at 03:38