Ian Fiddes
Ian Fiddes

Reputation: 3001

slicing tuples backwards - how to handle getting the first element?

Let's say I want elements 1-3 of a tuple, backwards:

x = (0,1,2,3,4)
x[1:4]

Returns (1,2,3)

And

x[3:0:-1]

Returns (3,2,1)

But what if I want elements 0-2?

I can do x[2::-1] to get the correct answer of (2,1,0) but x[2:0:-1] returns (2,1) and x[2:-1:-1] returns ().

Is there a way to slice to the last item without using a if statement if I am slicing at unknown intervals?

Upvotes: 3

Views: 267

Answers (4)

Alex Reynolds
Alex Reynolds

Reputation: 96937

Perhaps merge a "reverse-sentinel" tuple with your original tuple, and subscript that:

>>> x = (0, 1, 2, 3)
>>> y = (0,)

Then:

>>> (y + x)[3:0:-1]
(2, 1, 0)
>>> (y + x)[2:0:-1]
(1, 0)

Not as fast as Peter DeGlopper's solution, though:

#!/usr/bin/env python

import time

x = tuple(range(0,int(1e6)))
y = (0,)

start_time = time.time()
a = (y+x)[3:0:-1]
print("tuple add --- %s seconds ---" % (time.time() - start_time))

start_time = time.time()
b = x[0:3][::-1]
print("tuple rev --- %s seconds ---" % (time.time() - start_time))

Not even close, really:

$ ./test61.py
tuple add --- 0.0153260231018 seconds ---
tuple rev --- 6.19888305664e-06 seconds ---

Upvotes: 0

Kasravnd
Kasravnd

Reputation: 107287

with x[-n:] you can get the last n index and with [::-1] you can inverse it !

>>> x[-2:][::-1]
(4, 3)
>>> 

Upvotes: 0

Peter DeGlopper
Peter DeGlopper

Reputation: 37319

One slightly inefficient way:

x[0:3][::-1]

Which is equivalent to:

tuple(reversed(x[0:3]))

I'm not sure offhand how well the unnecessary intermediate tuple gets optimized away.

Upvotes: 3

Mark Ransom
Mark Ransom

Reputation: 308130

You can use None in place of the empty element:

x[2:None:-1]

Upvotes: 2

Related Questions