[:]是什么意思?

9
return self.var[:]

这会返回什么?
5个回答

9

Python允许您“切片”各种容器类型;这是一种缩写符号,用于获取有序集合的某些子集。例如,如果您有一个列表

foo = [1,2,3,4,5]

如果你想要获取第二、第三和第四个元素,可以这样做:
foo[1:4]

如果在切片中省略了一个数字,它将默认为列表的开头。例如:
foo[1:] == [2,3,4,5]
foo[:4] == [1,2,3,4]

当然,如果在切片中省略两个数字,您将获得整个列表!但是,您将获得列表的副本而不是原始列表;实际上,这是复制列表的标准符号。请注意以下区别:

>>> a = [1,2,3,4]
>>> b = a
>>> b.append(5)
>>> a
[1, 2, 3, 4, 5]
>>>
>>> a = [1,2,3,4]
>>> b = a[:]
>>> b.append(5)
>>> a
[1, 2, 3, 4]

这是因为 b = a 告诉 b 指向与 a 相同的对象,因此向 b 添加元素就相当于向 a 添加元素。复制列表 a 可以避免这种情况。请注意,这只会运行一级间接深度 - 如果 a 包含一个列表,并且您在 b 中添加了该列表中的元素,则仍会更改 a

顺便说一下,切片还有一个可选的第三个参数,即步长参数 - 它可以让您以大于1的跨度移动列表。因此,您可以编写 range(100)[0::2] 来获取所有小于100的偶数。


1
或者你可以编写 range(0, 100, 2)。 - John Machin
还可以用于对切片进行赋值,例如 a[2:4] = [4,5,6,7,8] - John La Rooy

5
如果self.var是一个可变序列,它将返回该序列的浅拷贝
如果self.var是一个不可变的内置序列,比如stringtuple,大多数实现将返回self.var本身。

如果 var 指向一个可变序列,它将返回该序列的浅拷贝的引用。如果 var 指向一个不可变序列(例如 str、unicode 和 tuple),为了效率应该返回原始引用。 - John Machin
@John,你评论的第一部分技术上是正确的,但我不确定第二部分(请看我的回答中的最后一个链接)。另外,我认为提问者更感兴趣的是代码实际上做了什么,而不是它应该做什么 :) - Frédéric Hamidi
“should”的强调:对于内置对象,使用CPython的第二种情况将返回原始引用(因为实现者并不傻)。对于用户定义的对象,则没有这样的保证。在[:]的情况下,“共享切片”(您的最后一个链接)与非愚蠢实现已经“共享”无关。 - John Machin

2
这将创建列表的浅拷贝,并将其返回。
“浅拷贝”与“深拷贝”相对,意味着列表仅会创建其中引用的新副本,而非实际对象。也就是说,将创建一个具有相同对象引用的新列表,但对象本身将保持不变。
如果您从原始列表中删除一个项目,则新列表不受影响,但如果您更改原始列表中的一个元素(例如通过调用方法或设置对象属性),则该元素在新列表上也会发生变化,因为虽然它们是不同的列表,但指向相同的对象。

谁说它是一个列表?它可以是任何支持切片操作的对象,例如xlm.etree.ElementTree.Element对象。 - John Machin
当然,你是对的。我本可以说“任何实现切片功能的对象”,但我认为这几乎没有帮助——这不是问题的重点,我认为浅拷贝与深拷贝的问题才是重要的部分。 - salezica

2

这被称为列表切片:

[起始位置:终止位置:步长]

[起始位置:终止位置]

因此,如果我说:

list = range(20)
print list[1:3] #returns [2, 3]
print list[1:12:3] #returns [2, 5, 8, 11]
print list[14:] #because theres no end: [15, 16, 17, 18, 19]
print list[14:-2] #-2 from the end: [15, 16, 17]

它被称为切片,是由几种不同类型的对象提供的操作。 - John Machin

1

你可以使用以下方式对列表使用运算符:

list=[1,2,3,4,5,6,7,8,9]

在方括号中间加上一个冒号,您就可以定义要选择的位置范围(起始位置为0)。因此我有以下选项:

list[0:3] 显示 [1,2,3],因为它从第一个数字的位置开始,并在第二个数字之前结束。

list[:3] 与之前相同,因为第一个数字不存在,所以没有开始限制。

list[5:] 显示从第五个位置到结尾的列表 [6,7,8,9]。

现在,如果 list[x,y] 中的 x 或 y 是负数,则它会从位置 x 开始(如果是 x),从 len(list)-2 位置结束(如果是 y)。 例如:list[-1:3]= [2,3]

现在您可以使用两个冒号 [x:y:z],其中 x 表示起始单元格,y 表示最后一个单元格(不包括返回区域),而 z 表示序列前进的步骤。 list[0:5:2]=[0,2,4]


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