I think this is best explained by comparison with C/C++. Take this function:
void swap(int &x, int &y) {
int temp = *x;
*x = *y;
*y = temp;
}
This code does what you want it to do, but it's impossible in Python. Here's why:
The critical part of the C function is the function signature *x, *y
which makes the arguments a pointer. When you do *x = *y, you are overwriting the memory that x
points to. In python, you can't pass a pointer, only a reference. The difference is that overwriting a reference does nothing to the original object. For example,
x = "foo"
y = x
x = "bar"
print(x, y) # bar, foo not bar, bar
Any approach to solving this problem must deal with this issue, such as @adamgy's answer. His approach uses a double reference. You pass something that can i) hold references and is ii) mutable. He uses a list, but you could use a dict or any mutable object.
PS: There might be a way to do this using the CPython API, which is a little extreme.
All Python objects in the standard implementation have an underlying C object. You can implement a python function in C.
static PyObject * swap(PyObject *a, PyObject *b)
{
// logic
}
It might be possible to design a function that takes a pointer to a pointer.
static PyObject * swap(PyObject *a, PyObject *b)
{
swap_internal(&a, &b);
// more logic
}
static PyObject * swap_internal(PyObject **a, PyObject **b)
{
// logic
}
This would have the necessary double reference semantics, but I haven't checked if it actually works.