在Python中删除列表的第一个元素

Deleting first element of a list in Python

我知道,如果我只想删除python中list t的第一个元素,我可以用以下方法来完成:

1
del t[0]

这是最简单的。然而:

1
t = t[1:]

同样有效。在我正在学习的教科书中说,使用后一种方法通常被认为是不好的做法,因为它本身并不删除列表的标题,但是

"slice运算符创建一个新的列表,赋值使t引用它,但没有一个引用它。"对作为参数传递的列表有任何影响。"

为什么这样不好?你能举出一个例子,在这个例子中,这样的方法会显著地改变一个函数吗?事先谢谢。


这不是一个好主意有多种原因:

  • 创建一个新列表只需要做一些不必要的工作来创建新列表和取消分配旧列表。在这两个步骤之间,两次使用内存(因为原始列表和新列表同时处于活动状态,就在分配之前)。

  • 如果有其他内容引用同一个列表,则不会更新:u = t; del t[0]同时更改u和t。但u = t; t = t[1:]在保持u不变的情况下将新列表分配给t。

  • 最后,与不透明的t = t[1:]相比,del t[0]更清楚地说明了其去除元素的强度。


考虑具有两个实现的函数:

1
2
3
4
5
def remove_first_a(t):
    t = t[1:]  

def remove_first_b(t):
    del t[0]

现在,请参见正在使用的功能:

1
2
3
4
5
6
7
> l = [1, 2, 3]
> remove_first_a(l)
> l
[1, 2, 3]
> remove_first_b(l)
> l
[2, 3]

第一个实现只重新分配局部变量t,它对作为参数传递的对象没有影响。第二个实现实际上改变了该对象。第一个函数在其当前形状中相当无用。你可以改变它:

1
2
3
4
5
6
7
def remove_first_a(t):
    return t[1:]

> l = [1, 2, 3]
> x = remove_first_b(l)
> x
[2, 3]

你想要一个还是另一个,更多地取决于实际的用例。有时,您希望原始的EDOCX1[1]保持不变以供以后使用,有时您希望确保在仍然引用它的所有地方更改原始的。


只是del和slice的一个例子。

1
2
3
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运算符。

1
2
3
4
5
In [31]: del t[0]
In [32]: t
Out[32]: [2, 3, 4]
In [33]: u
Out[33]: [2, 3, 4]

但是如果我们使用slice操作符。

1
2
3
4
5
6
7
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现在指向不同的对象,所以我们处理列表T,列表U不变。