-2

I am playing with Python and found a script online which contains a function. I wrote a simple analogous example below:

def func(thing):
    test = thing[0,:]
    print(test)

I do not know what datatype the variable "thing" is in this case. What kind of Python datatype/object can be called with square brackets like this?

If you run (using my example above) the variable "thing" as an np.array, dict or list, I get the error: "list indices must be integers or slices, not tuple"

  • Neither NumPy array nor dict will call them self a list. – Kelly Bundy Oct 26 '22 at 18:52
  • Why was this reopened? I'm not quite sure how this isn't a duplicate: https://stackoverflow.com/questions/216972/what-does-it-mean-if-a-python-object-is-subscriptable-or-not – esqew Oct 26 '22 at 18:54
  • @esqew That's not about tuples as indices. – Kelly Bundy Oct 26 '22 at 18:55
  • Apologies if it is poorly posed i just have genuinely never seen something be called with square brackets like this before – 13deadfrogs Oct 26 '22 at 18:59
  • 1
    Check out https://stackoverflow.com/questions/9972391/python-array-slice-with-comma... – Samwise Oct 26 '22 at 19:00
  • 1
    @Samwise Right, and the lowest-voted answer there even talks about more than just NumPy (so that's good for this question). I don't think I saw that when I reopened, only saw that other question shown by esqew and disagreed with that. – Kelly Bundy Oct 26 '22 at 19:02

1 Answers1

0

I do not know what datatype the variable "thing" is in this case. What kind of Python datatype/object can be called with square brackets like this?

Any object that has a __getitem__ method can be subscripted.

thing[0, :]

is simply syntactic sugar for

thing.__getitem__((0, slice(None, None, None)))

So, it is up to that object whether it wants to accept one, two, three, four, or however many parameters and whether it wants to accept certain types of parameters.

For example, the following can generate the error message you posted:

class Foo:
  def __getitem__(self, x):
    if not isinstance(x, (int, slice)):
      raise TypeError(f"list indices must be integers or slices, not {type(x)}")

foo = Foo()

foo[0, :]

The reason for the somewhat cryptic error is that multiple indices are desugared into a tuple. So, a __getitem__ which only expects a single parameter will be passed a tuple argument.

Jörg W Mittag
  • 363,080
  • 75
  • 446
  • 653