11

I want to write code like this:

index = 0:2
print(list[index])

but this does not work.

Is there any way I can store all parts of the [...:...] syntax in a variable?

Bhargav Rao
  • 50,140
  • 28
  • 121
  • 140

2 Answers2

24

You want a slice() object:

index = slice(0, 2)
print(somelist[index])

slice() models the start, stop and stride values you can specify in the [start:stop:stride] subscription syntax, as an object.

From the documentation:

Return a slice object representing the set of indices specified by range(start, stop, step). The start and step arguments default to None. Slice objects have read-only data attributes start, stop and step which merely return the argument values (or their default).

Under the covers, Python actually translates subscriptions to a slice() object when calling custom __getitem__ methods:

>>> class Foo(object):
...     def __getitem__(self, item):
...         return item
...
>>> Foo()[42:81:7]
slice(42, 81, 7)
>>> Foo()[:42]
slice(None, 42, None)

A viable alternative would be to store start and stop as separate values:

startindex = 0
stopindex = 2
print(somelist[start:stop])
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • thanks, but what about "index = -2:" – giorgi shengelaia Nov 10 '16 at 16:06
  • @giorgishengelaia Your doing it wrong. Just store the `index` variable with a value of `-2`. Then say `print(somelist[index:])`. – Christian Dean Nov 10 '16 at 16:07
  • 1
    @giorgishengelaia: that be `slice(-2, None)`. Try out my `Foo()` example; `Foo()[-2:]` returns `slice(-2, None, None)`. – Martijn Pieters Nov 10 '16 at 16:08
  • 2
    @leaf: what if you wanted to model `-2:` at one time, and `:4` another? – Martijn Pieters Nov 10 '16 at 16:08
  • @MartijnPieters I'm not sure I see what your getting at? – Christian Dean Nov 10 '16 at 16:10
  • 2
    @leaf: your approach, `index = -2` and `somelist[index:]` limits you to only making the starting point variable. You could use *three* variables, one for start, stop and stride, respectively, then use `somelist[start:stop:stride]` everywhere, but that's very verbose. Using a `slice()` object is far more elegant here. – Martijn Pieters Nov 10 '16 at 16:13
  • @MartijnPieters I'm sorry, I don't get your argument. In his second question, I didn't see any need for a `slice()` object because he only had a start value. Why should he use `slice()` instead of a slice variable with one value? – Christian Dean Nov 10 '16 at 16:16
  • @MartijnPieters You got me right. – giorgi shengelaia Nov 10 '16 at 16:17
  • @leaf I want to use "index = -2:" and "index = 0:2" at the same time. – giorgi shengelaia Nov 10 '16 at 16:19
  • 1
    @leaf: Yes, in their example they only had a start variable. Yet in the question they had an *end variable* (ignoring the start defaulting to `0`). So this is clearly a question about modelling all portions of a slice, not just a single value in a slice. – Martijn Pieters Nov 10 '16 at 16:19
  • @leaf: comments are not for extended discussion however. If you want to talk more about this, I'm in the [Python chat room](https://chat.stackoverflow.com/rooms/6/python). – Martijn Pieters Nov 10 '16 at 16:19
  • if I wanted to use only "index = -2:", I would not use variable("index") – giorgi shengelaia Nov 10 '16 at 16:20
11

You can instead create a slice object:

index = slice(0,2)
print(lst[index])

Be careful not to use list as name to avoid shadowing the builtin list function.

From the docs:

slice(start, stop[, step])

Return a slice object representing the set of indices specified by range(start, stop, step)

Moses Koledoye
  • 77,341
  • 8
  • 133
  • 139