所以我在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的一部分会改变级别以及如何修复它。
非常感谢
答案 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
否则,您有两个对同一列表的引用,而不是两个单独的列表。