编辑重复列表会编辑原始列表

时间:2013-07-17 15:28:03

标签: python list python-2.7

所以我在python中开始了一个简单的roguelike游戏项目,但我在编辑原始的重复列表方面遇到了问题。代码如下:

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)

如您所见,我创建了名为level的列表,其中列表中的每个列表都是一行。表示开始行和列位置的字符。

然后循环询问您是要向上,向左还是向下移动。它会检查是否有挡墙(#字符),并做出相应的反应。

正如您所看到的,它复制了一个名为display_level的级别,然后将“@”作为字符放在显示级别上。然而问题是更改display_level也没有明显的原因改变级别,即使它们是分开的,每次循环遍历它都会使display_level = level。

然后单独打印display_level和level,它显示正在编辑的level_level旁边的级别,这不应该发生。

所以我想知道的是为什么更改display_level的一部分会改变级别以及如何修复它。

非常感谢

3 个答案:

答案 0 :(得分:4)

创建level的副本。您所做的只是创建对相同列表的另一个引用。

要创建列表的副本,您可以从头到尾对其进行切片:

display_level = level[:]

但是对于你的情况,还不够。您需要复制嵌套列表。在这种情况下,列表理解最简单:

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

更全面的解决方案是使用copy.deepcopy() function使绝对确定顶级对象和所有包含的对象都是副本:

import copy

# ...

display_level = copy.deepcopy(level)

答案 1 :(得分:1)

将变量分配给另一个变量引用不重复。请改用copy()

>>> l = range(10)                    # assign original list
>>> l                                # display list (l)   
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a = l                            # assign a to l
>>> a                                # display list (a)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> a.remove(4)                      # remove '4' item from a
>>> a                                # display list (a)
[0, 1, 2, 3, 5, 6, 7, 8, 9]          # notice that '4' is gone   
>>> l                                # display list (l)
[0, 1, 2, 3, 5, 6, 7, 8, 9]          # notice that '4' is *also* gone   
>>> import copy                      # import the copy module
>>> b = copy.deepcopy(l)             # create a deepcopy of l called b
>>> b                                # display list (b)
[0, 1, 2, 3, 5, 6, 7, 8, 9]          # notice, '4' is still gone.
>>> l                                # display list (l)
[0, 1, 2, 3, 5, 6, 7, 8, 9]          
>>> b.remove(3)                      # remove '3' item from b
>>> b                                # display list (b)   
[0, 1, 2, 5, 6, 7, 8, 9]             # notice, '3' is gone. 
>>> l                                # display list (l)
[0, 1, 2, 3, 5, 6, 7, 8, 9]          # notice, '3' is still there.

注意:有一些“更简单”的方式,或复制Martijn's Answer

中详述的列表的“快捷方式”

答案 2 :(得分:1)

您应该通过执行以下操作制作列表清单的新副本:

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

而不是:

display_level=level

否则,您有两个对同一列表的引用,而不是两个单独的列表。