0

I'm new here and looking for some advice.

I'm learning how to use Python (3.8) by implementing a game I made. Every new topic I see, I restart it more or less from scratch to introduce and practice the new elements I learned. I'm currently trying to get the hang of Classes.

I stumble in this problem with "lists", though: I want a "Class" to create numbered Objects. For this I've created a blank list (players_vector = []) and with a "for" loop I append new objects to that list. So I can access each object by their index on that list: players_vector[i].player_color for example.

The problem I can't understand:

player_vector[i].pawn_coordinates is a list like [[x1,y1], [x2, y2]] # There are two Pawns.

Every time I try to change one of those for one of the players (e.g.: players_vector[2].pawn_coordinates[0] = [new_x, new_y]) all the other players have that same pawn's coordinates changed to the same value too. (Other attributes like player_color work fine)

A piece of code that reproduces the problem:

import pyinputplus as pyip

WIDTH = 5
HEIGHT = 5
players_vector = []

class Player:
    def __init__(
        self,
        player_color=None,
        pawn_position=[-1, -1],
        pawn_coordinates=[[-1, -1], [-1, -1]],
        pawn_previous_position=[-1, -1]
    ):
        self.player_color = player_color
        self.pawn_position = pawn_position
        self.pawn_coordinates = pawn_coordinates
        self.pawn_previous_position = pawn_previous_position
        self.player_score = 0

    def return_position(self, WIDTH, pawn_index):
        return WIDTH*(self.pawn_coordinates[pawn_index][1]-1)+(self.pawn_coordinates[pawn_index][0]-1)

players_vector.append(Player('Brown'))
players_vector.append(Player('Orange'))
players_vector.append(Player('White'))

def place_pawns(WIDTH, players_vector):
        print(
            f"Player {players_vector[1].player_color}, please enter the starting coordinates for your Pawns:"
        )
        x = pyip.inputNum(f"Enter X (1-5) for your 1st Pawn: ", min=1, max=5)
        y = pyip.inputNum(f"Enter Y (1-5) for your 1st Pawn: ", min=1, max=5)
        players_vector[1].pawn_previous_position[0] = players_vector[1].pawn_position[0]
        players_vector[1].pawn_coordinates[0] = [x, y]
        players_vector[1].pawn_position[0] = players_vector[1].return_position(WIDTH, 0)
        x = pyip.inputNum(f"Enter X (1-5) for your 2nd Pawn: ", min=1, max=5)
        y = pyip.inputNum(f"Enter Y (1-5) for your 2nd Pawn: ", min=1, max=5)
        players_vector[1].pawn_previous_position[1] = players_vector[1].pawn_position[1]
        players_vector[1].pawn_coordinates[1] = [x, y]
        players_vector[1].pawn_position[1] = players_vector[1].return_position(WIDTH, 1)

place_pawns(WIDTH, players_vector) 

print(f'Coordinates: {players_vector[0].pawn_coordinates} Color: {players_vector[0].player_color}')
print(f'Coordinates: {players_vector[1].pawn_coordinates} Color: {players_vector[1].player_color}')
print(f'Coordinates: {players_vector[2].pawn_coordinates} Color: {players_vector[2].player_color}')

print('Then trying to change the first [x,y] of White to [3,2] and the Orange color to Green')
players_vector[2].pawn_coordinates[0] = [3,2]
players_vector[1].player_color = 'Green'

print(f'Coordinates: {players_vector[0].pawn_coordinates} Color: {players_vector[0].player_color}')
print(f'Coordinates: {players_vector[1].pawn_coordinates} Color: {players_vector[1].player_color}')
print(f'Coordinates: {players_vector[2].pawn_coordinates} Color: {players_vector[2].player_color}')
  • Sorry, it's just the mutable default argument, not the "list of lists". – mkrieger1 Oct 26 '20 at 20:42
  • Default arguments are evaluated *once* at function definition time. Every time you use that default argument, it is *sharing the same object*. – juanpa.arrivillaga Oct 26 '20 at 20:42
  • Oh, that is not intuitive at all. But indeed, if I remove the default arguments, it works as intended. I saw there's an answer talking about the "mutable default arguments". I don't understand much, but thank you very much! – Gustavo 'Scary' Oct 26 '20 at 20:54

0 Answers0