Krab
Krab

Reputation: 6756

Python list slice

Why the first output is including the first element (is seems to me like good behavior, because it starts with 0 index (that is that first element) and then increment with len(a)-1 (last element)).

Problem is that the second example (if it always starts with zero index and then increment) should be something like [1, 5, 4, 3, 2], or?

Output 1: [1, 5]

Output 2: [5, 4, 3, 2, 1]

a = [1, 2, 3, 4, 5]

print(a[::len(a)-1])

print(a[::-1])

Upvotes: 0

Views: 129

Answers (4)

lvc
lvc

Reputation: 35069

When you provide a negative step, the defaults for start and stop are (roughly) switched: it will start at the end of the list, and stop at the beginning. I say 'roughly' because, as you've seen, it is adjusted so that a[::-1] still includes all of the elements of a - meaning, it is actually equivalent to a[-1:-len(a):-1]. The reason for this is likely related to how awkward that syntax is, compared to how useful reversing a sequence is compared to it meaning a[0:-1:-1], which is empty.

This is true of all builtins that support this syntax (lists, tuples and strings), but not necessarily true of any types from 3rd party modules that support it (it is up to the individual classes what slicing means for them).

Upvotes: 0

Santosh Ghimire
Santosh Ghimire

Reputation: 3145

Here is how python list slicing works:

a[start:end] # items start through end-1

There is also the step value, which can be used with any of the above:

a[start:end:step] # start through not past end, by step

The other feature is that start or end may be a negative number, which means it counts from the end of the array instead of the beginning. So:

a[-1]    # last item in the array
a[-2:]   # last two items in the array
a[:-2]   # everything except the last two items

So, in your case,

a[::len(a)-1] slices the array from start to end with step of len(a)-1 = 4 i.e. [1, 5] (skips the three items and retains the fourth one)

a[::-1] inverts the array.

Upvotes: 2

aelor
aelor

Reputation: 11116

what you have is called extended slices whatever you mention after :: is the step value you wan to add to the 0 index element

so

>>> print(a[::len(a)-1])
[1, 5]

is basically

 >>> print(a[::4)
    [1, 5]

get the 0 th element and add 4 to the index and get me the next element.

Similar behaviour for negative numbers.

>>> print(a[::-1)
        [5, 4, 3, 2, 1]

add -1 to the index ( or subtract 1 from the index ) which makes it 0-1 or 5(the last element in the array).

Upvotes: 2

thefourtheye
thefourtheye

Reputation: 239473

The last parameter in a slice is the step value. It starts from 0, if the step is positive, -1 if the step is negative. Relevant piece of code from sliceobject.c,

defstart = *step < 0 ? length-1 : 0;

So, when you say

a[::-1]

and as the step is negative, it just starts from the last element. It keeps on incrementing the index by -1 and the generated list is returned. So, it basically reverses the list.

But, when you say

a[::len(a)-1]

the step value is 4. Since the step is positive, it starts from the first element, which is 1 and increments the index by 4 and picks the element at index 4 (initial index (0) + 4 = 4), which is 5. That is why [1, 5] is returned.

Upvotes: 4

Related Questions