带切片的范围说明

问题描述 投票:2回答:3

456怎么变成459

>>> a = range(123, 456, 7)[1::4]  
>>> print(a)
range(130, 459, 28)
python python-3.x range slice
3个回答
1
投票

首先。

a = range(123, 456, 7)
print(list(a))
#[123, 130, 137, 144, 151, 158,.....431, 438, 445, 452]

即我们得到一个123到456的列表,步长为7

然后我们尝试下一步。

a = range(123, 456, 7)[1::4]
print(list(a))
#[130, 158, 186, 214, 242, 270, 298, 326, 354, 382, 410, 438]

这相当于起点为130的范围,步长为28,最后一个值为459,即range(130, 459, 28),它还告诉您从第1个元素开始从范围中取出每个第4个元素。


1
投票

请注意,如果您创建的切片不会更改任何内容,也会发生这种情况:

>>> b = range(123, 456, 7)
>>> print(b[::1])
range(123, 459, 7)

该范围中包含的最后一个数字是452,因此任何值452 < stop <= 459都会为您提供相同的输出。鉴于未包含的第一个值是步长为1的停止,因此将其用于其他步骤也更为一致;它允许您通过从停止中减去步骤来快速确定包含的最后一个值。


然而,我不知道的是,为什么28的新步骤不遵循逻辑;在此基础上,如果结果是:

>>> b[1::4]
range(130, 466, 28)

所以你可以很容易地计算出包含的最后一个值是438.但是,任何值438 < stop <= 466都会给出相同的输出,所以459并不完全错误。


1
投票

你的结果都基本相同。

在python 3中ranges是immutable sequences,在python 2中它们返回一个列表:

a = range(123, 456, 7)[1::4]  # generate a range spaced 7 apart, take every 4th

python 2.7:

print(a) 
> [130, 158, 186, 214, 242, 270, 298, 326, 354, 382, 410, 438]

python 3.6:

print(a)
> range(130, 459, 28)

print(*range(130, 459, 28))
> 130 158 186 214 242 270 298 326 354 382 410 438

你的切片告诉range只能将每个第4个元素用于7个间隔范围。 4*7 == 28:这就是range“改变”的原因。

重新计算的范围切片将其上限更改为起始值+步长的倍数 - 并且range的上限是独占的,因此如果它被称为456459439并不重要 - 只要它大于那么您从该范围最后生成的数字。

© www.soinside.com 2019 - 2024. All rights reserved.