This works:
x = ['foo', 'bar']
y = [*x]
print(y) # prints ['foo', 'bar']
but this doesn't:
x = ['foo', 'bar']
y[*x] # raises SyntaxError (not NameError!)
How can I unpack tuples while indexing?
Here are two examples where I'd like to use this approach, but I'm more interested in understanding why *
-unpacking seems not to be supported in indexing in general.
import numpy as np
def lookup(a: np.ndarray, coordinates: tuple) -> float:
return a[*coordinates]
a1 = np.zeros((2, 2))
print(lookup(a1, (0, 1)) # Should print 0
a2 = np.zeros(2, 2, 2))
print(lookup(a2, (0, 0, 1)) # Should print 0
or
from typing import Tuple
NUM_DIMENSIONS = 2 # Might change at a later point in time
# Should be equivalent to Tuple[float ,float]
Result = Tuple[*([float] * NUM_DIMENSIONS)]
def get() -> Result:
...
Python's indexing already has built-in support for tuples in general (not just for NumPy), so there is no need for unpacking here.
In general, foo[x]
is syntactic sugar for type(foo).__getitem__(foo, x)
. Let's see how that works in detail:
class Foo:
def __getitem__(self, key):
print(repr(key))
foo = Foo()
If we index into foo
with a single value then it is passed to __getitem__
unchanged, no matter whether it is a scalar, a list, or a tuple:
foo[0] # prints 0
foo[(0, 1)] # prints (0, 1)
foo[[0, 1]] # prints [0, 1]
The interesting case is what happens when we supply multiple values directly while indexing (without wrapping them in a tuple or list):
foo[0, 1] # prints (0, 1)
So multiple values are automatically wrapped in a tuple! foo
cannot distinguish between foo[0, 1]
and foo[(0, 1)]
. This is because in the Python grammar, the index is an expression (or a slice, but that doesn't apply here) -- and in an expression, a ,
forms a tuple:
x = 1, 2
print(repr(x)) # prints (1, 2)
Hence, argument parsing in indexing works differently then for function calls (where commas separate arguments instead of forming tuples).
So, overall, there is no need for iterator unpacking in indexing. Simply convert your iterator to a tuple use it as the index.