Reputation: 169
How did 456
become 459
?
>>> a = range(123, 456, 7)[1::4]
>>> print(a)
range(130, 459, 28)
Upvotes: 2
Views: 103
Reputation: 51683
Both your results are essentially the same.
In python 3 range
s 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
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
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