RSSregex
RSSregex

Reputation: 169

Explanation of range with slice

How did 456 become 459?

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

Upvotes: 2

Views: 103

Answers (3)

Patrick Artner
Patrick Artner

Reputation: 51683

Both your results are essentially the same.

In python 3 ranges are immutable sequences, in python 2 they return a list:

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]

pyton 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

Your slicing tells the range to only take every 4th element for its 7-spaced-apart range. 4*7 == 28: that is why the range "changes".

The recalculated range-slice changes its upper bound to startvalue + multiple of your stepsize - and the upper bound of the range is exclusive, so it does not really matter if it is called 456 or 459 or 439 - as long as it is bigger then the number you generate last from the range.

Upvotes: 1

jonrsharpe
jonrsharpe

Reputation: 122154

Note this also happens if you make a slice that doesn't change anything:

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

The last number included in that range is 452, so any value 452 < stop <= 459 would give you the same output. Given that the first value that isn't included is the stop with a step of 1, it's more consistent to use that for other steps too; it allows you to quickly determine what the last value that is included will be by subtracting the step from the stop.


What I don't know, though, is why that logic isn't followed for the new step of 28; on that basis it would be helpful if the result was:

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

so you could easily work out that the last value included was 438. However, any value 438 < stop <= 466 will give the same output, so 459 isn't exactly wrong.

Upvotes: 0

Devesh Kumar Singh
Devesh Kumar Singh

Reputation: 20500

To begin with.

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

i.e we get a list from 123 to 456, with a step size of 7

Then we try the next step.

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

Which is equivalent to range with start of 130, with a step size of 28, and the last value is 459, which is range(130, 459, 28), which also tells you to take every 4th element from the range, starting from the 1st element.

Upvotes: 1

Related Questions