Not sure what the arguments inside the [ ]
really do after the range()
function.
Exp: print ( range(5)[::-2])
Output: [4, 2, 0]
But if [x:y:z]
stands for [start:stop:step]
, then when I put print(range(5)[4:-2:-2])
, the output list is [4]
instead of [4, 2, 0]
, not sure how that works.
Python range() Function The range() function returns a sequence of numbers, starting from 0 by default, and increments by 1 (by default), and stops before a specified number.
The range() function, on the other hand, returns a list or sequence of numbers and consumes more memory than xrange() . Since the range() function only stores the start, stop, and step values, it consumes less amount of memory irrespective of the range it represents when compared to a list or tuple.
For the python course there is a question that asks: for i in range(10): if not i%2==0 print(i+1) What does this print? The answer that is told is that it "prints out all even numbers between 2 and 10.
The range() gives the sequence of numbers and returns a list of numbers. The xrange() function gives a generator object that needs to be looped in a for-loop to get the values. The range() returns a list. xrange() returns a generator object.
In Python 3, range()
creates a special range
object. In Python 2, it creates a list
.
List element: 0 1 2 3 4
Index: 0 1 2 3 4
Backwards index: -5 -4 -3 -2 -1
So, going from index 4
to index -2
really goes from list element 4
to list element 3
. Since you're skipping every other element, you don't get to 3
, leaving you with merely [4]
.
You’re right, it’s [start:stop:step]
. Note that negative starts and stops are defined to start at the end of the sequence. So for a range that ends with the values 2, 3, 4
, the stop -2
refers to the 3
(-1 is the last, -2 is the second to last, etc.).
So in your case, the range has a length of 5, starting at 0 and ending at 4. You start at the index 4, and end at the index -2 which is 5-2 = 3
. So so far, the index refers to [3, 4]
. Now, starting at 4, you have a negative step of 2. So you skip over the 3, resulting in just [4]
.
If you want [4, 2, 0]
, then you should leave out the stop:
>>> range(5)[4::-2]
[4, 2, 0]
You can actually even leave out the start:
>>> range(5)[::-2]
[4, 2, 0]
but
range(5)[4:-2]
results[]
. Then howrange(5)[4:-2:-2]
results[4]
?
The slice is evaluated at once, not one argument after another:
After evaluating the negative stop, range(5)[4:-2]
is equivalent to range(5)[4:3]
. Since there is no step specified, the default step of positive 1 will be used. This means that the slice would have to go from index 4 to index 3 with a positive step. That’s impossible, so an empty list is returned.
When we have a negative step, it looks like this: range(5)[4:3:-2]
. Now, since we have a negative step, the direction is reversed. So we can start at an index 4 and go to a lower index 3.
It’s just defined that for a positive step, stop >= start
needs to be true, and for a negative step the inverse, stop <= start
.
Slices with three arguments defined in terms of [start:stop:step]
. Coincidentally, that's also how range objects are defined with three arguments. We'll see how that comes into play soon.
What you are doing is this:
>>> range(5)
[0, 1, 2, 3, 4]
>>> range(5)[4:-2:-2]
[4]
Negative indices in Python wrap around from the length of the sequence. So the length of your list is 5, and then you go two steps down with -2, so you get index 3 as your stop value. In other words, index 3 is the sentinel value for the iterator at which point, the slice operation will stop collecting elements. You'll be stepping down 2 indices every step, but index 3 is the sentinel, so the slice stops collecting elements after it grabs the element at index 4 and reaches the stop index.
What you probably actually want to do is this:
>>> range(4, -2, -2)
[4, 2, 0]
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With