Editing a duplicate list edits the original
Question: So I've started a simple sort of roguelike game project in python, but I have
problems with editing a duplicate list editing the original. The code is as
follows:

    
    
    charx = 1
    chary = 1
    level = [["#","#","#","#","#","#","#"],["#",".",".",".",".",".","#"],["#",".","#",".",".",".","#"],["#","#","#","#","#","#","#"]]
    while True:
        move = raw_input("u,d,l or r: ")
        if move=="u":
            if level[chary-1][charx]!="#":
                chary-=1
        elif move=="d":
            if level[chary+1][charx]!="#":
                chary+=1
        elif move=="r":
            if level[chary][charx+1]!="#":
                charx+=1
        elif move=="l":
            if level[chary][charx-1]!="#":
                charx-=1
        display_level=level
        display_level[chary][charx]="@"
        for row in display_level:
            print "".join(row)
        for row2 in level:
            print ",".join(row2)
    

As you can see I have created list called level, where each list inside the
list is a row. The characters starting row and column position is stated.

Then the loop asks whether you want to move up, down left or right. It checks
to see if there is a wall (the # character) in the way and reacts accordingly.

As you can see, it makes a duplicate of the level called display_level and
then puts an "@" as the character onto display level. The problem is however
is that changing display_level changes level as well for no apparent reason,
even though they are separate and each time the loop runs through it makes
display_level=level.

display_level and level are then printed separately and it shows level being
edited along side display_level which shouldn't happen.

So what I want to know is why changing an part of display_level would change
level and how I can fix it.

Much appreciated


Answer: You are _not_ creating a duplicate of `level`. All you do is create another
reference to the _same list_.

To create a copy of a list, you can just slice it from start to end:

    
    
    display_level = level[:]
    

but for your case, that is _not enough_. You need to copy the _nested_ lists.
In this case, a list comprehension is easiest:

    
    
    display_level = [l[:] for l in level]
    

A more comprehensive solution is to use the [`copy.deepcopy()`
function](http://docs.python.org/2/library/copy.html#copy.deepcopy) to make
_absolutely sure_ that the top-level object and all contained objects are
copies:

    
    
    import copy
    
    # ...
    
    display_level = copy.deepcopy(level)
    

