类对象(列表)具有奇怪的行为

时间:2015-08-23 18:33:10

标签: python tkinter

我最近修补了Tkinter,我决定做一些简单的游戏。我选择经典的蛇类游戏。一切顺利,但我遇到了list的奇怪行为,这是蛇对象的容器。我试图编程后续蛇段的传播,到目前为止每次尝试都失败了。代码简单直接,但在这种情况下,它根本无法正常工作。

对象self.snake_object看起来像这样。处于初始状态。

    self.snake_object = [[312, 192, 1, 'left'],
                         [336, 192, 2, 'left'],
                         [360, 192, 3, 'left'],
                         [384, 192, 4, 'left']]

换句话说。

    self.snake_object[[cord_x, cord_y, seg_num, label]]

    #Every segment of the snake is in list and those lists are contained in another list.
    #cord_x - coordinate x of corresponding segment.
    #cord_y - coordinate y of corresponding segment.
    #seg_num - number corresponding segment.
    #label - information where is forward of the segment.

这是代码。

    old_snake_object = self.snake_object
    new_snake_object = self.snake_object

    for s in range(0, len(old_snake_object)-1):
        if old_snake_object[s][3] != new_snake_object[s+1][3]:
            new_snake_object[s+1][3] = old_snake_object[s][3]

    self.snake_object = new_snake_object

即使是更粗糙的形式,这也不起作用。

    old_snake_object = self.snake_object
    new_snake_object = self.snake_object

    for s in range(0, len(old_snake_object)-1):
        if old_snake_object[s][3] == 'left':
            new_snake_object[s+1][3] = 'left'
        elif old_snake_object[s][3] == 'right':
            new_snake_object[s+1][3] = 'right'
        elif old_snake_object[s][3] == 'up':
            new_snake_object[s+1][3] = 'up'
        elif old_snake_object[s][3] == 'down':
            new_snake_object[s+1][3] = 'down'

    self.snake_object = new_snake_object

如果您需要帮助,我可以通过整个代码。写一下。

2 个答案:

答案 0 :(得分:0)

Python不会在分配上复制列表,它们只是引用。制作一份明确的副本:

old_snake_object = self.snake_object
new_snake_object = self.snake_object[:]

for s in range(0, len(old_snake_object)-1):
    if old_snake_object[s][3] != new_snake_object[s+1][3]:
        new_snake_object[s+1][3] = old_snake_object[s][3]

self.snake_object = new_snake_object

答案 1 :(得分:0)

我找到了答案。 实际上,列表的副本存在问题,在本例中为self.snake_object。问题是您无法将列表中的项目复制到新列表,只需在这两个列表之间写入等号即可。此方法使此新列表仅引用旧列表中的给定项目集。丹尼尔清楚地说明了这一点并感谢你。

有简单的证明。

>>> a = [1, 2, 3]
>>> b = a
>>> b[0] = 4
>>> print(a)
[4, 2, 3]

但是您无法通过在新列表的末尾添加“[:]”来复制列表。它仍然只是引用旧列表。

>>> a = [1, 2, 3]
>>> b = a[:]
>>> b[0] = 4
>>> print(a)
[4, 2, 3]

将事物从一个列表复制到另一个列表的最快方法是import copy模块并使用copy.deepcopy()方法。

>>> import copy
>>> a = [1, 2, 3]
>>> b = copy.deepcopy(a)
>>> b[0] = 4
>>> print(a)
[1, 2, 3]
>>> print(b)
[4, 2, 3]