gpt4 book ai didi

Python:为什么列表元素在使用程序后仍然没有消失?

转载 作者:太空宇宙 更新时间:2023-11-03 12:27:43 25 4
gpt4 key购买 nike

我定义这个函数来做:[1,2,3] --> [2,3,1]

def shift_to_left(p):
p.append(p[0])
return p[1:]

当我这样检查时,结果没问题:

p1 = [1,2,3]
print p1
p1 = shift_to_left(p1)
print p1

The result:
[1, 2, 3]
[2, 3, 1]

但是,当我引入另一个列表并在进行时连接时,结果是不同的:

ss = []
p1 = [1,2,3]
ss.append(p1)
p1 = shift_to_left(p1)
ss.append(p1)

print ss

The result
[[1, 2, 3, 1], [2, 3, 1]]

But I want:
[1,2,3]
[2,3,1]

为什么会这样?

非常感谢,

最佳答案

在 Python 中,大多数参数都是通过引用获取的。

您的函数 shift_to_left 实际上改变了它的参数(通过使用 append),但随后返回一个切片(它是列表的浅拷贝)。

当您将原始变量替换为 shift_to_left 的输出时,此行为将被隐藏:

In [1]: def shift_to_left(p):
...: p.append(p[0])
...: return p[1:]
...:

In [2]: xs = [1, 2, 3]

In [3]: xs = shift_to_left(xs)

In [4]: xs
Out[4]: [2, 3, 1]

但是如果我们将结果赋给一个变量,我们可以看到原来的列表确实已经改变了:

In [5]: ys = shift_to_left(xs)

In [6]: ys
Out[6]: [3, 1, 2]

In [7]: xs
Out[7]: [2, 3, 1, 2]

我们的结果 ysxs 从第二个元素开始的切片。这就是您所期望的。

但是xs 本身被调用append 改变了:它现在比以前长了一个元素。这就是您在第二个示例中遇到的情况。


如果您想要这种行为,避免它的一种方法是将列表的副本传递给shift_to_left:

In [8]: zs = shift_to_left(ys[:])

In [9]: zs
Out[9]: [1, 2, 3]

In [10]: ys
Out[10]: [3, 1, 2]

在这里,您可以看到原始列表 ys 没有被修改,因为 shift_to_left 被赋予了它的副本,而不是对象本身。 (当然,这仍然是通过引用传递;它只是不是对 ys 的引用)。


或者,可能更合理的是,您可以更改 shift_to_left 本身,这样它就不会修改其参数:

def shift_to_left(xs):
return xs[1:] + xs[0] # build a new list in the return statement

这两种方法的一个大问题是它们会创建大量列表副本,当列表很大时,这可能会非常慢(并使用大量内存)。


当然,正如@Marcin 指出的那样,如果这不仅仅是一项学术练习,您可能应该使用一种内置数据结构,例如 deque

关于Python:为什么列表元素在使用程序后仍然没有消失?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27790754/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com