我之前正在玩一些代码,我注意到一些相当奇怪的东西,而我却无法解释它。
除了一件事之外,下面是两个完全相同的功能。变量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
仅在真实时更新;它没有。它确实可以作为元组值正常工作。为什么是这样?如果我在其他地方意外更改了值,则会在元组函数中引发错误,因为元组是静态的,并且如果函数其他部分的逻辑关闭,则元组函数将输出与列表函数相同的函数
这种情况发生的原因是什么?
答案 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
您只需使用引用,即originalPos
和pos
是同一对象的两个名称。
将其更改为:
originalPos = pos[:]
你得到:
>>> ticking_as_list()
[110, 110]
这与元组版本的结果相同。