我知道如果我想在Python中删除列表 t 的第一个元素,我可以用:
del t[0]
这和它一样简单明了。但是:
t = t[1:]
也有效。在我从中学习的教科书中说,使用后一种方法通常被认为是不好的做法,因为它不会删除列表的头部本身但是
"切片运算符创建一个新列表,并且赋值使得它引用它,但没有一个 对作为参数传递的列表有任何影响。"
为什么这么糟糕?你能说出一个这样的方法会显着改变一个函数的例子吗?提前谢谢。
答案 0 :(得分:5)
这不是一个好主意有多种原因:
创建新列表只会使新列表和取消分配旧列表成为不必要的工作。在这两个步骤之间,使用了两倍的内存(因为原始列表和新列表同时存在,就在赋值之前)。
如果其他内容引用相同的列表,则不会更新:u = t; del t[0]
同时更改 u 和 t 。但u = t; t = t[1:]
将新列表分配给 t ,同时保持 u 不变。
最后,del t[0]
更清楚地了解了删除元素的意图,而不是更不透明的t = t[1:]
。
答案 1 :(得分:2)
考虑具有两种实现的函数:
def remove_first_a(t):
t = t[1:]
def remove_first_b(t):
del t[0]
现在,请查看正在使用的功能:
> l = [1, 2, 3]
> remove_first_a(l)
> l
[1, 2, 3]
> remove_first_b(l)
> l
[2, 3]
第一个实现仅重新分配 local 变量t
,该变量对作为参数传递的对象没有影响。第二个实现实际上改变了该对象。第一个功能在其目前的形状中相当无用。你可以改变它:
def remove_first_a(t):
return t[1:]
> l = [1, 2, 3]
> x = remove_first_b(l)
> x
[2, 3]
您是否想要其中一个,更多地取决于实际用例。有时您希望原始list
仍然保持不变以供以后使用,有时您希望确保原始文件在仍然具有引用的所有位置都会更改。
答案 2 :(得分:1)
只是del和slice的一个例子。
In [28]: u = t = [1, 2,3,4]
In [30]: id(u) == id(t) # now the id is same,they point one obj
Out[30]: True
如果我们使用del运算符。
In [31]: del t[0]
In [32]: t
Out[32]: [2, 3, 4]
In [33]: u
Out[33]: [2, 3, 4]
但是如果我们使用切片运算符。
In [35]: t = t[1:]
In [36]: t
Out[36]: [2, 3, 4]
In [37]: id(t) == id(u)
Out[37]: False
In [39]: u
Out[39]: [1, 2, 3, 4]
我们发现t和u指向不同的obj.so我们处理列表t,列表u没有改变。