Объяснение диапазона с ломтиком - PullRequest
2 голосов
/ 22 апреля 2019

Как 456 стало 459?

>>> a = range(123, 456, 7)[1::4]  
>>> print(a)
range(130, 459, 28)

Ответы [ 3 ]

1 голос
/ 22 апреля 2019

Для начала.

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), что также говорит о том, что нужно взять каждый 4-й элемент из диапазона, начиная с 1-го элемент.

1 голос
/ 22 апреля 2019

Оба ваших результата по существу одинаковы .

В Python 3 range s неизменяемые последовательности , в 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]

питон 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 «меняется».

пересчитанный диапазон-срез меняет свою верхнюю границу на startvalue + кратную вашего шага - и верхняя граница range является эксклюзивной, поэтому не имеет значения, если она называется 456 или 459 или 439 - если оно больше, чем число, которое вы генерируете последним из диапазона.

0 голосов
/ 22 апреля 2019

Обратите внимание, что это также происходит, если вы делаете срез, который ничего не меняет:

>>> 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 не совсем неверно.

...