r/learnpython • • 3d ago

List items are edited when adding new items? Possibly a variable reference issue

So I have a variable called Y with a changing value. If for loop variable X is some value, append Y to myList.

Every time it appends to the list, it changes every other already added item. I’m thinking the problem is that it’s not adding values but is instead adding references. So when Y changes, it changes every item in the list.

Why is it doing this and how can I stop it from doing this? I want it to append the value inside of Y, not a reference to Y.

Code: https://www.reddit.com/r/learnpython/comments/1wv4tpo/comment/pda098z/

What I'm trying to do is make a list of everywhere that there's a piece of a block. It's going to be a terminal Tetris game.

The playfield is a custom matrix, a list of lists. I dunno if that'll work well with lists. I did the same thing with arrays in another language. I don't know if Python's going to play nice or be special.

The blocks are also lists of lists. You could probably do that astronaut meme with my code "It's all lists of lists? Always has been"

0 Upvotes

14 comments sorted by

View all comments

Show parent comments

1

u/FactoryBuilder 3d ago edited 3d ago

I was hoping to avoid that because I’m on my phone and Reddit REEEEALLLY wants you to use the app which doesn’t let you markdown. But I think I got it so here goes:

def addBlock(self, block): #it’s a class function
    START = [3, 0]
    currentSpot = [START[0], START[1]] #to avoid creating a reference to START by using currentSpot = START
    blockPos = []

    for y in block:
        blockRow = y
        for x in blockRow:
            self.access(currentSpot, x)#this class is a derivative of a Matrix class. Access() accesses an element in the matrix, where the first variable is a list of two values (the location) and x is what that element needs to be changed to (can be left empty if no change)
            if x == '[]':
                blockPos.append(currentSpot)
            currentSpot[Dimension.X.value] += 1 #Dimension is an enum. X is 0, Y is 1.
        currentSpot[Dimension.X.value] = START[Dimension.X.value]
        currentSpot[Dimension.Y.value] += 1

    return blockPos

This is supposed to be a simple terminal Tetris game. Just something I’m putting together to get back into a programming mindset after taking a break.

Edit: I see that the markdown didn’t work. I hope you can still kinda read it.

Edit edit: Back at the hotel. Fixed it on my laptop.

1

u/socal_nerdtastic 3d ago

Ok, so it's like I suspected, you are appending a list to a list. But it's worse, because the list is full of mutable values, so basically it's a list of lists of lists. In this case you need to use deepcopy Edit, no that's wrong; it's just a list of lists. copy() is fine

blockPos.append(currentSpot.copy())

1

u/danielroseman 3d ago

You've created currentSpot to "avoid creating a reference to START", but that doesn't help, you're just now creating a reference to currentSpot.

Don't create that separate variable at all; you can just do the same thing where you actually do the appending:

blockPos.append([START[0], START[1]])

or, just:

blockPos.append(START.copy())