2
votes

My understanding of tuple is it can be enclosed with parenthesis.

Tuples may be constructed in a number of ways:

Using a pair of parentheses to denote the empty tuple: ()
Using a trailing comma for a singleton tuple: a, or (a,)
Separating items with commas: a, b, c or (a, b, c)
Using the tuple() built-in: tuple() or tuple(iterable)

Basic Slicing and Indexing says slice indexing is a tuple of slice objects and int.

Basic slicing occurs when obj is a slice object (constructed by start:stop:step notation inside of brackets), an integer, or a tuple of slice objects and integers.

However, (...) cannot be used causing an error. Is the error from numpy or Python?

I suppose without parenthesis, 0:1, 2:3, 1 is still a tuple but why cannot use parenthesis if it is specified as a tuple of slice objects and integers?

It is not so important but after struggling with numpy indexing, this makes it further confusing, hence a clarification would help.

Z = np.arange(36).reshape(3, 3, 4)
print("Z is \n{}\n".format(Z))

a = Z[
    (0:1, 2:3, 1)
]
---
  File "<ipython-input-53-26b1604433cd>", line 5
    (0:1, 2:3, 1)
      ^
SyntaxError: invalid syntax

This works.

Z = np.arange(36).reshape(3, 3, 4)
print("Z is \n{}\n".format(Z))

a = Z[
    0:1, 2:3, 1
]
print(a)
print(a.base is not None)

As per the comment by hpaulj, numpy s_ internally takes "a list of slices and integers" and returns a tuple of slice objects.

from numpy import s_
print(s_[0:1, 2:3, 1])

Z = np.arange(36).reshape(3, 3, 4)
print("Z is \n{}\n".format(Z))

print(Z[s_[0:1, 2:3, 1]])
---
(slice(0, 1, None), slice(2, 3, None), 1)
Z is 
[[[ 0  1  2  3]
  [ 4  5  6  7]
  [ 8  9 10 11]]

 [[12 13 14 15]
  [16 17 18 19]
  [20 21 22 23]]

 [[24 25 26 27]
  [28 29 30 31]
  [32 33 34 35]]]

[[9]]
1
There's a numpy indexing tool that can turn slice and ellipsis syntax into a tuple of objects: np.s_[1:2, ...] produces a tuple: (slice(1, 2, None), Ellipsis). Note that s_ is used with [], not (). - hpaulj

1 Answers

4
votes

Slice notation like 1:2 is syntax, it does not create an object, so you cannot use them in a list or tuple or anything; slice objects on the other hand actually refer to the thing returned by slice() which behave the same, and that's what Numpy is referencing with "tuple of slice objects and integers". The valid syntax to do what you were expecting would be Z[(slice(1, 2), slice(2, 3), 1)]. This allows you to save slices to a variable and use them instead.

Here's a simple code snippet to demonstrate:

>>> 1:2
  File "<stdin>", line 1
SyntaxError: illegal target for annotation
>>> slice(1, 2)
slice(1, 2, None)
>>> [1, 2, 3][1:2]
[2]
>>> [1, 2, 3][slice(1, 2)]
[2]