简体   繁体   中英

Python, making shallow copy of a list doesn't work with object attributes?

I am trying to make a shallow copy of a list, this list is stored in an object's attribute. Even though my shallow copy is in a function it doesnt work, I tried

copy.copy 

temp = list(actuallist)

temp = actuallist[:]

Here is related parts of my current code

This is the object

class Game:

    tiles = []
    daleks = []
    rawtile = ""
    height = 20
    width = 20
    tilesize = 32
    gamemap = "default"
    status = 0
    doctor = ""
    screen = ""
    clock = pygame.time.Clock()

    def __init__(self,height,width,tilesize,gamemap):
        self.height = height
        self.width = width
        self.tilesize = 32
        self.gamemap = gamemap
        self.status = 0
        size = (tilesize*width, tilesize*height)
        self.screen = pygame.display.set_mode(size)
        pygame.display.set_caption("Doctor Who vs Daleks")

    def teleportDoctorIn(self,classname):
        self.doctor = classname

    def releaseDalek(self,x):
        self.daleks.append(x)

    def resetDaleks(self):
        daleks = []

This is the part where I create a shallow list and change it

def updateMap(x,y):
    temp = game.tiles[:]
    """SET DOCTOR COORDS"""
    temp[game.doctor.xpos][game.doctor.ypos] = "X"
    game.doctor.move(x,y)
    temp[game.doctor.xpos][game.doctor.ypos] = "D"
    """LETS MOVE DALEKS"""

Turns out i needed to copy.deepcopy() the list.

Your three techniques make shallow copies of the list. So even though the list itself is unque - and you can do things like adding and removing elements on one without affecting the other - the contained objects are the same. temp[game.doctor.xpos][game.doctor.ypos] = "X" changes the contained object which is still held by both lists.

As an example, lets just put some dict s in a list and see what happens

>>> import copy
>>> d1={1:'one', 2:'two'}
>>> d2={3:'three', 4:'four'}
# create a list then copy it
>>> l1=[d1, d2]
>>> l2=l1[:]

# l1 and l2 are different, but their members are the same
>>> id(l1) == id(l2)
False
>>> id(l1[0]) == id(l2[0])
True

# and if you change the objects in l2, they change l1
>>> l1[0]
{1: 'one', 2: 'two'}
>>> l2[0][5]='five'
>>> l1[0]
{1: 'one', 2: 'two', 5: 'five'}

# but a deep copy copies the contained objects also so no problem
>>> l3=copy.deepcopy(l1)

# the contained objects are not the same
>>> id(l1[0]) == id(l3[0])
False

# and changing one does not affect the other
>>> l1[0]
{1: 'one', 2: 'two', 5: 'five'}
>>> l3[0]
{1: 'one', 2: 'two', 5: 'five'}
>>> l3[0][6] = 'six'
>>> 
>>> l1[0]
{1: 'one', 2: 'two', 5: 'five'}
>>> l3[0]
{1: 'one', 2: 'two', 5: 'five', 6: 'six'}
>>> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM