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

9

我知道如果我想要在Python中仅删除列表t的第一个元素,可以使用以下方法:

del t[0]

这个问题非常直白明了。但是:
t = t[1:]

也可以工作。我所学习的教材中说,通常认为使用后一种方法是不好的实践,因为它并没有真正删除列表的头部,而是……

“切片操作符创建一个新列表,赋值使 t 引用它,但这对传递作为参数的列表没有任何影响。”

为什么这样做不好?您能否举出一个例子,说明这样的方法会显着改变函数?提前感谢。


1
如果你特别想要做的是从列表中删除第一个元素,使用不这样做的方法是不好的实践。这并不意味着t = t[1:]在一般情况下是不好的实践。 - user2357112
此外,您可以使用t[:] = t[1:]修改原始列表。 - TigerhawkT3
1
有很多情况下,del t[0]t = t[1:] 都可以使用,也有很多情况下,del t[0] 是错误的,而 t = t[1:] 则是合适的。 - user2357112
你可以使用 t.pop(0),它会返回列表中第一个元素的值并将其从列表中移除。 - darvark
1
@darvark - OP并不是在问如何从列表中移除一个项目的其他方法,而是在询问修改原始列表与创建新列表的使用情况。 - TigerhawkT3
3个回答

6

这不是一个好的做法有以下多个原因:

  • 创建新列表只是做了不必要的工作,造成新列表的内存分配和老列表的释放。而在两步之间,会使用两倍的内存(由于原始列表和新列表同时存在,就在赋值之前)。

  • 如果其他东西引用了同一个列表,则不会得到更新:u = t; del t[0] 更改了ut。但是 u = t; t = t[1:] 将新的列表分配给t,而不更改u

  • 最后,del t [0]比更加晦涩的 t = t[1:] 更清晰地表达了其删除元素的意图。


我认为t[:] = t[1:]可以用于改变现有的列表对象,但它需要大约两倍于del t[0]的工作量,因为del操作只需将所有后续列表项向下移动,而t[1:]必须将后续项复制到新列表中,然后再将它们复制回原始列表对象。这样说对吗? - PM 2Ring

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]

第一个实现仅重新分配了没有对传递的对象产生影响的本地变量t。第二个实现实际上改变了该对象。第一个函数在其目前的形式下相当无用。您可以进行更改:

def remove_first_a(t):
    return t[1:] 

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

你需要选择哪种方式,更多取决于实际的使用情况。有时候你希望原始的list仍然存在且不变,以备后续使用,而有时候你想确保所有引用到它的地方都会改变原始的list


1

只是一个关于删除和切片的示例。

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 现在指向不同的对象。因此,我们处理列表 t,而列表 u 不会改变。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接