我知道如果我想要在Python中仅删除列表t的第一个元素,可以使用以下方法:
del t[0]
这个问题非常直白明了。但是:
t = t[1:]
也可以工作。我所学习的教材中说,通常认为使用后一种方法是不好的实践,因为它并没有真正删除列表的头部,而是……
“切片操作符创建一个新列表,赋值使 t 引用它,但这对传递作为参数的列表没有任何影响。”
为什么这样做不好?您能否举出一个例子,说明这样的方法会显着改变函数?提前感谢。
我知道如果我想要在Python中仅删除列表t的第一个元素,可以使用以下方法:
del t[0]
t = t[1:]
也可以工作。我所学习的教材中说,通常认为使用后一种方法是不好的实践,因为它并没有真正删除列表的头部,而是……
“切片操作符创建一个新列表,赋值使 t 引用它,但这对传递作为参数的列表没有任何影响。”
为什么这样做不好?您能否举出一个例子,说明这样的方法会显着改变函数?提前感谢。
这不是一个好的做法有以下多个原因:
创建新列表只是做了不必要的工作,造成新列表的内存分配和老列表的释放。而在两步之间,会使用两倍的内存(由于原始列表和新列表同时存在,就在赋值之前)。
如果其他东西引用了同一个列表,则不会得到更新:u = t; del t[0]
更改了u和t。但是 u = t; t = t[1:]
将新的列表分配给t,而不更改u。
最后,del t [0]
比更加晦涩的 t = t[1:]
更清晰地表达了其删除元素的意图。
t[:] = t[1:]
可以用于改变现有的列表对象,但它需要大约两倍于del t[0]
的工作量,因为del
操作只需将所有后续列表项向下移动,而t[1:]
必须将后续项复制到新列表中,然后再将它们复制回原始列表对象。这样说对吗? - PM 2Ring考虑一个具有两个实现的函数:
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
。
只是一个关于删除和切片的示例。
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
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 不会改变。
t = t[1:]
在一般情况下是不好的实践。 - user2357112t[:] = t[1:]
修改原始列表。 - TigerhawkT3del t[0]
或t = t[1:]
都可以使用,也有很多情况下,del t[0]
是错误的,而t = t[1:]
则是合适的。 - user2357112t.pop(0)
,它会返回列表中第一个元素的值并将其从列表中移除。 - darvark