22

I know that a[end:start:-1] slices a list in a reverse order.

For example

a = range(20)
print a[15:10:-1] # prints [15, ..., 11]
print a[15:0:-1] # prints [15, ..., 1]

but you cannot get to the first element (0 in the example). It seems that -1 is a special value.

print a[15:-1:-1] # prints []  

Any ideas?

Naveen Kumar Alone
  • 7,536
  • 5
  • 36
  • 57
Mohammad Moghimi
  • 4,636
  • 14
  • 50
  • 76

6 Answers6

22

You can assign your variable to None:

>>> a = range(20)
>>> a[15:None:-1]
[15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
>>> 
zhangyangyu
  • 8,520
  • 2
  • 33
  • 43
  • 1
    This (using `None`) is probably the best solution, but note that you can also use negative indices all the way around: `a[-5:-21:-1]` gets you the same slice, including the final `a[0]` element. – torek Jul 12 '13 at 08:35
  • @torek I also thought of using negative indices, but I think that is the best solution, because you can avoid the extra assignment to `None` (see my answer). – Paulo Almeida Jul 12 '13 at 10:07
15

Omit the end index:

print a[15::-1]
Pablo
  • 8,644
  • 2
  • 39
  • 29
8

In Python2.x, the simplest solution in terms of number of characters should probably be :

>>> a=range(20)

>>> a[::-1]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

Though i want to point out that if using xrange(), indexing won't work because xrange() gives you an xrange object instead of a list.

>>> a=xrange(20)
>>> a[::-1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sequence index must be integer, not 'slice'

After in Python3.x, range() does what xrange() does in Python2.x but also has an improvement accepting indexing change upon the object.

>>> a = range(20)
>>> a[::-1]
range(19, -1, -1)
>>> b=a[::-1]
>>> for i in b:
...     print (i)
... 
19
18
17
16
15
14
13
12
11
10
9
8
7
6
5
4
3
2
1
0
>>> 

the difference between range() and xrange() learned from source: http://pythoncentral.io/how-to-use-pythons-xrange-and-range/ by author: Joey Payne

cookie_chu
  • 81
  • 1
  • 2
  • Wut? Is this an answer? – Mohammad Moghimi Jul 19 '16 at 17:40
  • My direct answer is just a[::-1]. The following part is some possible complications people may find if they are using different version of python. Sorry about the confusion. I am new here, do you think i should delete the non-direct answer part and where should i put it? Thanks! – cookie_chu Jul 21 '16 at 14:51
1
>>> a
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
>>> print a[:6:-1]
[19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7]
>>> a[7] == a[:6:-1][-1]
True
>>> a[1] == a[:0:-1][-1]
True

So as you can see when subsitute a value in start label :end: it will give you from start to end exclusively a[end].

As you can see in here as well:

>>> a[0:2:]
[0, 1]

-1 is the last value in a:

>>> a[len(a)-1] == a[-1]
True
0x90
  • 39,472
  • 36
  • 165
  • 245
0

EDIT: begin and end are variables

I never realized this, but a (slightly hacky) solution would be:

>>> a = range(5)
>>> s = 0
>>> e = 3
>>> b = a[s:e]
>>> b.reverse()
>>> print b
[2, 1, 0]
Ludo
  • 813
  • 1
  • 9
  • 21
0

If you use negative indexes you can avoid extra assignments, using only your start and end variables:

a = range(20)
start = 20
for end in range(21):
    a[start:-(len(a)+1-end):-1]
Paulo Almeida
  • 7,803
  • 28
  • 36