29

Is there any way in python to use a tuple as the indices for a slice? The following is not valid:

>>> a = range(20)
>>> b = (5, 12)   # my slice indices
>>> a[b]          # not valid
>>> a[slice(b)]   # not valid
>>> a[b[0]:b[1]] # is an awkward syntax
[5, 6, 7, 8, 9, 10, 11]
>>> b1, b2 = b
>>> a[b1:b2]      # looks a bit cleaner
[5, 6, 7, 8, 9, 10, 11]

It seems like a reasonably pythonic syntax so I am surprised that I can't do it.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Mike
  • 2,637
  • 5
  • 29
  • 40

4 Answers4

48

You can use Python's *args syntax for this:

>>> a = range(20)
>>> b = (5, 12)
>>> a[slice(*b)]
[5, 6, 7, 8, 9, 10, 11]

Basically, you're telling Python to unpack the tuple b into individual elements and pass each of those elements to the slice() function as individual arguments.

Chinmay Kanchi
  • 62,729
  • 22
  • 87
  • 114
13

How about a[slice(*b)]?

Is that sufficiently pythonic?

Eugene Yarmash
  • 142,882
  • 41
  • 325
  • 378
Foon
  • 6,148
  • 11
  • 40
  • 42
  • I had completely forgotten about python's `*args` syntax. It would be more pythonic though if I could just write `a[*b]`. Of course this would conflict with multi-dimensional arrays so the ordinary slicing syntax is still better. Inclusion of the word slice is longer but probably far more clearly illustrates the purpose of the code. – Mike Aug 15 '11 at 22:19
4

slice takes up to three arguments, but you are only giving it one with a tuple. What you need to do is have python unpack it, like so:

a[slice(*b)]
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
2

Only one tiny character is missing ;)

In [2]: a = range(20)

In [3]: b = (5, 12)

In [4]: a[slice(*b)]
Out[4]: [5, 6, 7, 8, 9, 10, 11
Martin Thurau
  • 7,564
  • 7
  • 43
  • 80