PEP-0637 Support for indexing with keyword arguments

Abstract

At present keyword arguments are allowed in function calls, but not in item access.

This PEP proposes that Python be extended to allow keyword arguments in item access.

The following example shows keyword arguments for ordinary function calls:

>>> val = f(1, 2, a=3, b=4)

The proposal would extend the syntax to allow a similar construct to indexing operations :

>>> val = x[1, 2, a=3, b=4]  # getitem
>>> x[1, 2, a=3, b=4] = val  # setitem
>>> del x[1, 2, a=3, b=4]    # delitem

and would also provide appropriate semantics .

This PEP is a successor to PEP 472 , which was rejected due to lack of interest in 2019. Since then there’s been renewed interest in the feature.

Use cases

The following practical use cases present different cases where a keyword specification would improve notation and provide additional value:

  1. To provide a more communicative meaning to the index, preventing e.g. accidental inversion of indexes:

>>> grid_position[x=3, y=5, z=8]
>>> rain_amount[time=0:12, location=location]
>>> matrix[row=20, col=40]
  1. To enrich the typing notation with keywords, especially during the use of generics:

def function(value: MyType[T=int]):
  1. In some domain, such as computational physics and chemistry, the use of a notation such as Basis[Z=5] is a Domain Specific Language notation (DSL) to represent a level of accuracy:

>>> low_accuracy_energy = computeEnergy(molecule, BasisSet[Z=3])
  1. Pandas currently uses a notation such as:

>>> df[df['x'] == 1]

which could be replaced with df[x=1].

  1. xarray has named dimensions. Currently these are handled with functions .isel:

>>> data.isel(row=10)  # Returns the tenth row

which could also be replaced with data[row=10]. A more complex example:

>>> # old syntax
>>> da.isel(space=0, time=slice(None, 2))[...] = spam
>>> # new syntax
>>> da[space=0, time=:2] = spam

Another example:

>>> # old syntax
>>> ds["empty"].loc[dict(lon=5, lat=6)] = 10
>>> # new syntax
>>> ds["empty"][lon=5, lat=6] = 10

>>> # old syntax
>>> ds["empty"].loc[dict(lon=slice(1, 5), lat=slice(3, None))] = 10
>>> # new syntax
>>> ds["empty"][lon=1:5, lat=6:] = 10

It is important to note that how the notation is interpreted is up to the implementation.

This PEP only defines and dictates the behavior of python regarding passed keyword arguments, not how these arguments should be interpreted and used by the implementing class.