lzb1001 发表于 2023-4-2 18:46:58

再问列表切片的负数步长

>>list =
>>list[::-3]
>>
没看懂返回值结果是怎么来的呢

liuhongrun2022 发表于 2023-4-2 18:55:21

这段代码的意思是先创建了一个列表 list,包括 1 到 6 的整数。然后使用列表切片的方式,从列表末尾开始每隔 3 个元素取一个元素,最后返回这些被选中的元素组成的新列表。具体来说:

[::-3] 表示取整个列表的逆序,步长为 3。
取到的第一个元素是 6,因为它是距离列表末尾最近的且索引可以被 3 整除的元素(即列表的倒数第一个元素)。
然后跳过两个元素,再次找到一个满足要求的元素 3(即列表的倒数第四个元素)。
再次跳过两个元素,没有更多满足要求的元素了,于是返回由 6 和 3 组成的新列表 。
需要注意的是,在切片时如果不指定起始索引和终止索引,则默认从列表的开头到结尾。而如果步长是负数,则表示从列表的结尾开始取元素。所以 [::-3] 可以看作是 len(list)-1::-3 的缩写形式,其中 len(list)-1 对应的是列表的最后一个元素的索引。

歌者文明清理员 发表于 2023-4-2 18:57:11

这是 Python 中列表(list)的一种切片方式,表示从列表的结尾到开头,每隔两个元素取一个元素,也就是取列表中索引值为 -1、-4 等位置上的元素。其中第一个冒号前面的空位表示起始位置,默认是 -1,第二个冒号后面的空位表示结束位置,默认是 -len(list)-1,而中间的数字 -3 表示步长,即每次跳过的元素个数。

因此,对于给定的 `list = `,`list[::-3]` 返回的是从最后一个元素开始,每隔两个元素取一个元素,直到遍历到列表的开头或者只剩下一个元素时停止。所以返回的结果是 ``,即列表中倒数第一个元素和倒数第四个元素构成的新列表。

isdkz 发表于 2023-4-2 18:58:36

当你在Python中使用列表的切片(slice)操作时,可以指定3个参数:起始索引、结束索引和步长。在你给出的例子中,你使用了一个负数作为步长:

list[::-3] 表示你希望从列表的末尾开始,按照步长3的方式向列表的开头方向遍历。[::-3] 的含义如下:

起始索引:默认为空,表示从列表的末尾开始。
结束索引:默认为空,表示遍历至列表的开头。
步长:-3,表示每次向前(左边)跳过2个元素(间隔为3)。
现在,让我们详细看一下列表的每个元素:

索引: 012345
元素: 123456

根据切片操作,我们从末尾开始(索引5,元素6),然后以步长-3向前遍历。第一次遍历,我们取到索引5的元素6。然后再向前跳过2个元素(索引3和4),取到索引2的元素3。此时已经到达列表的开头,所以切片操作完成。

因此,结果是。

lzb1001 发表于 2023-4-2 19:17:58

liuhongrun2022 发表于 2023-4-2 18:55
这段代码的意思是先创建了一个列表 list,包括 1 到 6 的整数。然后使用列表切片的方式,从列表末尾开始每 ...

还需要可以被 3 整除?

那如果刚好对应的两个元素都不能被3整数怎么办?

liuhongrun2022 发表于 2023-4-2 19:27:16

lzb1001 发表于 2023-4-2 19:17
还需要可以被 3 整除?

那如果刚好对应的两个元素都不能被3整数怎么办?

非常抱歉,我的回答有误,不必要求选取的元素下标必须能被 3 整除。

在这段代码中,切片 [::-3] 取反后每隔三个元素取一个元素。因此,在列表 list 中,第一个选定的元素是最后一个元素 6,然后需要跳过两个元素,然后查询下一个符合条件的元素,发现是倒数第四个元素 3,再次跳过两个元素发现没有下一个符合条件的元素了。所以最终选定的元素是 6 和 3,组成新列表 。

如果在这个过程中有某一步没有找到符合条件的元素,则会直接停止搜索,返回当前已经选定的元素组成的新列表。也就是说,如果在这个例子中没有找到一个元素的下标既是 3 的倍数又是列表长度的倍数,则它们之间的元素会被忽略掉。

感谢您提出问题,希望这次解释更加清晰明了。

lzb1001 发表于 2023-4-2 19:41:19

本帖最后由 lzb1001 于 2023-4-3 01:12 编辑

按我的理解:

ls[::-3]不是应该等于ls(前正后反),或者ls[-1:-7:3](前反后正)

然而:

ls(前正后反),或者ls[-1:-7:3](前反后正)返回的都是空列表[ ]

ls[::-3]实际真正应等于ls[-1:-7:-3]

isdkz 发表于 2023-4-2 19:45:58

lzb1001 发表于 2023-4-2 19:41
按我的理解:

ls[::-3]不是应该等于ls(前正后反),或者ls[-1:-7:3](前反后正)


我明白你的困惑。但实际上,当你使用负的步长时,起始索引和结束索引的默认值是不同的。这就是为什么 ls[::-3] 能得到 的结果。

当你使用负数作为步长时,起始索引默认值是列表的最后一个元素(即 -1),而结束索引默认值是列表的开始(实际上是空,因为不包括结束索引)。因此,ls[::-3] 实际上等于 ls[-1:None:-3]。

让我们再看一下切片操作的步骤:

索引:012345
元素:123456
负索引:-6 -5 -4 -3 -2 -1

现在,我们从末尾开始(索引 -1,元素 6),然后以步长 -3 向前遍历。第一次遍历,我们取到索引 -1 的元素 6。然后再向前跳过 2 个元素(索引 -3 和 -2),取到索引 -4 的元素 3。此时已经到达列表的开头,所以切片操作完成。

因此,结果是 。

对于你提到的其他两种写法:

ls:由于步长是负数,起始索引(1)比结束索引(7)大,所以返回空列表。
ls[-1:-7:3]:由于步长是正数,起始索引(-1)比结束索引(-7)小,所以返回空列表。

这就解释了为什么 ls[::-3] 的结果是 。

lzb1001 发表于 2023-4-2 20:02:11

isdkz 发表于 2023-4-2 19:45
我明白你的困惑。但实际上,当你使用负的步长时,起始索引和结束索引的默认值是不同的。这就是为什么 ls[ ...

容我消化和理解一下。

不过这也纠正一个我之前的错误认识:

小甲鱼在教材中举例:

>>list1 =
>>list1[::-1]
>>

因为教材前面提到:
>>list1[::]


可以简写成[::],

所以我之前一直以为list1[::-1] =

lzb1001 发表于 2023-4-2 20:17:56

>>list1 =

要想获得:

>>> list1[::-1] # 表达形式1


>>> list1[-1::-1] # 表达形式2


>>> list1[::-10:-1] # 不可!!!
SyntaxError: invalid syntax

----------------

要想获得:

>>> list1[:] # 表达形式1


>>> list1[::] # 表达形式2


>>> list1 # 表达形式3


>>> list1 # 表达形式4


>>> list1[:10] # 表达形式5


>>> list1[::10] # 不可!!!


>>> list1 # 表达形式6


>>> list1 # 不可!!!

lzb1001 发表于 2023-4-3 01:02:05

本帖最后由 lzb1001 于 2023-4-3 01:05 编辑

按2楼大神的意思是:list

按3楼大神的意思是: list[-1:-len(list)-1:-3]

都可以获得的返回结果

如果按我之前的错误理解:

>>> list

>>> list[-len(list)-1:-1:-3]

返回的都是空列表[]

lzb1001 发表于 2023-4-3 01:11:26

liuhongrun2022 发表于 2023-4-2 19:27
非常抱歉,我的回答有误,不必要求选取的元素下标必须能被 3 整除。

在这段代码中,切片 [::-3] 取反 ...

……也就是说,如果在这个例子中没有找到一个元素的下标既是 3 的倍数又是列表长度的倍数,则它们之间的元素会被忽略掉。

这句话确认没有错误?

lzb1001 发表于 2023-4-3 01:21:12

本帖最后由 lzb1001 于 2023-4-3 01:37 编辑

isdkz 发表于 2023-4-2 19:45
我明白你的困惑。但实际上,当你使用负的步长时,起始索引和结束索引的默认值是不同的。这就是为什么 ls[ ...

1、也可以按2楼大神的意思list,同样也可以得到相同的返回结果呢


2、我看不太明白红色字体:

ls:由于步长是负数,起始索引(1)比结束索引(7)大,所以返回空列表。 ----为什么1比7大?不是7大于1吗?
ls[-1:-7:3]:由于步长是正数,起始索引(-1)比结束索引(-7)小,所以返回空列表。----为什么-1比-7小?不是-7小于-1吗?

就是说:

如果步长是负数,起始索引必须比结束索引小,否则返回空列表。
如果步长是正数,起始索引必须比结束索引大,否则返回空列表。

大小是怎么比较?有点搞糊涂了


isdkz 发表于 2023-4-3 01:27:01

lzb1001 发表于 2023-4-3 01:21
按2楼大神的意思list也可以得到相同的返回结果呢

他的中间是没有 1 的,你这个不能等同于 list[::-3],因为他的结束索引不包含在内的

这里只是巧合结果一样而已,如果元素的个数刚好最后能取到第一个元素,你这个写法是不会包含第一个元素的

>>> list =
>>> list[::-3]

>>> list

>>> list

>>> list

>>>
页: [1]
查看完整版本: 再问列表切片的负数步长