【问题标题】:Python, making shallow copy of a list doesn't work with object attributes?Python,制作列表的浅表副本不适用于对象属性?
【发布时间】:2016-03-22 16:38:22
【问题描述】:

我正在尝试制作列表的浅表副本,此列表存储在对象的属性中。即使我的浅拷贝在一个不起作用的函数中,我尝试了

copy.copy 

temp = list(actuallist)

temp = actuallist[:]

这是我当前代码的相关部分

这是对象

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 = []

这是我创建一个浅表并对其进行更改的部分

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"""

原来我需要复制.deepcopy() 列表。

【问题讨论】:

  • 请详细说明它不起作用。它怎么不工作?你收到错误了吗?意想不到的结果?什么都没有?
  • 请从您的代码中删除所有不需要展示问题性质的内容。题目很简单,题怎么这么长?请阅读如何创建minimal example
  • temp[game.doctor.xpos][game.doctor.ypos] = "X" - 浅拷贝为您提供了一个新列表,但它并没有复制成员本身。 temp[game.doctor.xpos] 的对象与game.tiles[game.doctor.xpos] 的对象相同。我不知道你的意图是什么,但也许copy.deepcopy 是你想要的。
  • tdelaney,感谢您的回答。我现在明白我哪里做错了。

标签: python list object


【解决方案1】:

您的三种技术制作了列表的浅表副本。因此,即使列表本身是独特的——并且您可以在其中一个上添加和删除元素而不影响另一个——包含的对象是相同的。 temp[game.doctor.xpos][game.doctor.ypos] = "X" 更改了仍然由两个列表持有的包含对象。

举个例子,让我们将一些dicts 放在一个列表中,看看会发生什么

>>> 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'}
>>> 

【讨论】:

  • 深度复制 20x20 平铺列表会对我的代码产生多大影响?我正在制作一个简单的游戏,角色一次移动一步,每一步我都需要制作这个深层副本
  • 您可以使用timeit 模块来运行实验,但我认为它对 20x20 阵列的影响很小,我不会担心。特别是如果每​​个步骤都是用户启动的,相比之下按下enter 键所需的时间比较长。
  • 在我的代码中,每一步都是用箭头键完成的,所以当用户点击 KeyUp 时,角色的位置向上移动 1 格,然后地图内的“敌人”向主角移动 1 格,然后当所有的 AI 和计算完成后,我复制瓷砖以在屏幕上显示它,我使用 pygame 模块来可视化瓷砖等。我对编程相当陌生,这是我在 python 中的第一堂课,但我想学习挑战。
猜你喜欢
  • 2013-04-22
  • 2019-03-19
  • 2015-02-22
  • 2016-08-31
  • 1970-01-01
  • 1970-01-01
  • 2017-07-03
  • 2012-02-13
  • 1970-01-01
相关资源
最近更新 更多