列表值会更改它们应保持不变的位置

时间:2016-03-21 16:41:53

标签: python list tuples

我之前正在玩一些代码,我注意到一些相当奇怪的东西,而我却无法解释它。

除了一件事之外,下面是两个完全相同的功能。变量origionalPos是第一个函数中的列表,第二个函数中是元组。

def ticking_as_list():
    tick = False
    ticking = False
    originalPos = [0,0]
    pos = [0,0]

    x = 0
    RUNNING = True
    while RUNNING:
        x += 1
        if x % 50 == 0:
            tick = not tick
            ticking = not ticking

        if ticking:
            originalPos = pos
            ticking = False

        pos[0] = originalPos[0] + 10
        pos[1] = originalPos[1] + 10

        if x == 500:
            RUNNING = False
            print(pos)

def ticking_as_tuple():
    tick = False
    ticking = False
    originalPos = (0,0)
    pos = [0,0]

    x = 0
    RUNNING = True
    while RUNNING:
        x += 1
        if x % 50 == 0:
            tick = not tick
            ticking = not ticking

        if ticking:
            originalPos = (pos[0],pos[1])
            ticking = False

        pos[0] = originalPos[0] + 10
        pos[1] = originalPos[1] + 10

        if x == 500:
            RUNNING = False
            print(pos)

这些函数设置为更改pos的值,并且每次x可被50整除时为其添加10,并在结果等于500时打印结果。有更简单的方法可以做到这一点我知道,但这不是问题的主题。

当我运行这些函数中的任何一个时,我希望从它们中获得[110,110]的输出;当我实际运行它们时,输出如下:

>>> ticking_as_list()
[4520,4520]
>>> ticking_as_tuple()
[110,110]

ticking作为列表的函数显然远高于它是元组时的函数。当我在每个函数执行时通过打印pos来查看每个函数执行时发生的事情时,它表示在每次迭代时都会将{10}添加到pos,而在每次迭代时都会将其添加到元组时应该。

为什么即使值ticking等于false,列表也会始终更新?如代码所示:

        if x % 50 == 0:
            tick = not tick
            ticking = not ticking

        if ticking:
            originalPos = pos
            ticking = False

ticking仅在x可被50整除时才变为真,并且之后立即变为假。但是,哪个应该使originalPos仅在真实时更新;它没有。它确实可以作为元组值正常工作。为什么是这样?如果我在其他地方意外更改了值,则会在元组函数中引发错误,因为元组是静态的,并且如果函数其他部分的逻辑关闭,则元组函数将输出与列表函数相同的函数

这种情况发生的原因是什么?

3 个答案:

答案 0 :(得分:2)

originalPos = pos不会创建新列表,它只为现有列表提供新名称。要创建新列表,您可以使用空的list slice

originalPos = pos[:]

编辑:在Python 3.3中添加了一个明确的copy方法。

originalPos = pos.copy()

答案 1 :(得分:1)

    if ticking:
        originalPos = pos
        ticking = False

第二个语句使变量originalPos引用相同的列表作为pos,因此从那里改变一个也会改变另一个。您可能希望复制pos中的实际值,因此take a look at this answer

简而言之

originalPos = pos[:]

应该可以正常工作。

答案 2 :(得分:0)

区别在于:

originalPos = pos

您只需使用引用,即originalPospos是同一对象的两个名称。

将其更改为:

originalPos = pos[:]

你得到:

>>> ticking_as_list()
[110, 110]

这与元组版本的结果相同。