4

I recently read a code snippets about how to reverse a sequence

>> l = [1,2,3,4,5,6]
>> print l[::-1]

Output

>> [6,5,4,3,2,1]

How to explain the first colon in bracket?

Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
lazybios
  • 479
  • 8
  • 15
  • FYI, that is not the best way to reverse a sequence. Just use `list(reversed(l))`. – anon582847382 Mar 30 '14 at 14:38
  • why don't you get rid of it and see what happens? In other words address the list with only one colon [:-1] – PyNEwbie Mar 30 '14 at 14:38
  • @Alex what? How is that "better"? Maybe it's more general, but if you have a list or string I don't see any advantages to your approach (and it's longer, less idiomatic and probably slower) – Niklas B. Mar 30 '14 at 15:32

2 Answers2

10

The colons with no values given means resort to default values. The default values for the start index when the step is negative is len(l), and the end index is -len(l)-1. So, the reverse slicing can be written as

l[len(l):-len(l)-1:-1]

which is of the form.

l[start:end:step]

Removing the default values, we can use it in a shorter notation as l[::-1].

It might be useful to go through this question on Python's Slice Notation.

Community
  • 1
  • 1
Sukrit Kalra
  • 33,167
  • 7
  • 69
  • 71
  • 1
    `l[0:len(l):-1]` is something cmpletely different from `l[::-1]`. The equivalent would be `l[len(l):-len(l)-1:-1]`. – Niklas B. Mar 30 '14 at 15:35
  • @NiklasB. Thanks. I didn't think of that. Fixed that in the answer. :) – Sukrit Kalra Mar 30 '14 at 16:08
  • @SukritKalra I got it! The begin minus step to get the index.And first the `len(l)` is the last item in list until the the index equal to the `-len(l)-1` out range of the list.So we get the reverse list. – lazybios Apr 04 '14 at 02:14
2
some_list[start:end:step]

When you ommit any of the slicing operands they take on default values. Default values for start, end and step: start - the beginning of an indexated iterable which is always of an index 0 when step is positive, end - the ending index of an indexated iterable which is always its length (following the same convention as range) when step is positive, step - the default step is always one.

When you're using a minus sign on step omitting other operands you're basically saying "return a reversed list".

EDIT: Funny, but

[1,2,3,4,5,6][5:-7:-1]

returns the same result as

[1,2,3,4,5,6][::-1]

in Python3. Can anyone comment on to why? That means that default values of start and end actually rest upon the step operand (more specifically its sign).

Alisa D.
  • 134
  • 6
  • 1
    I think the idea is that `[start:end:step]` will visit the indices that would be visited by a loop like `for (idx = start; idx != end; idx += step)`. Negative indices `idx < 0` are interpreted as the "real" index `len(l) + idx`. `[5:-1:-1]` will not work because `-1` is interpreted as the index `len(l)-1`, so we need to use `-len(l)-1`, which is the "real" index -1 to force the iteration to include the index 0 – Niklas B. Mar 30 '14 at 15:38