在Python

时间:2017-03-26 06:22:26

标签: python python-3.x

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

del t[0]

这和它一样简单明了。但是:

t = t[1:]

也有效。在我从中学习的教科书中说,使用后一种方法通常被认为是不好的做法,因为它不会删除列表的头部本身但是

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

为什么这么糟糕?你能说出一个这样的方法会显着改变一个函数的例子吗?提前谢谢。

3 个答案:

答案 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没有改变。