I am trying to create a function that updates arguments inplace (mostly for curiosity's sake):
def inplaceUpdate(f, inputs):
for i in inputs:
i = f(i)
I have three inputs:
x = 1
y = 2
z = 3
And the function f
:
f = lambda i: i**2
I would like to run the following code:
inplaceUpdate(f, [x, y, z])
Then I would like for the values of x
, y
, and z
to change inplace. Is this possible?
x = 1
y = 4
z = 9
Answer
In Python, variables like x
, y
, and z
are immutable in the sense that you cannot change their values directly inside a function unless you pass them as mutable types or return updated values. In your inplaceUpdate
function, you're trying to modify the values of the variables x
, y
, and z
in place, but this won't work because integers are immutable in Python. When you assign i = f(i)
, it only changes the local reference of i
, not the original variable itself.
Why does this not work?
In the code:
def inplaceUpdate(f, inputs):
for i in inputs:
i = f(i)
Here, i
is a local variable in the loop. When you update i
with i = f(i)
, it only changes the local reference of i
. It does not affect the original variables passed in the list inputs
because integers (and other immutable objects like strings and tuples) cannot be modified in place like mutable objects (e.g., lists or dictionaries).
Solution: Using a Mutable Container
To achieve in-place updates for the values of x
, y
, and z
, you can pass a mutable container (like a list or dictionary) and modify the values inside that container. Here's how you can modify your approach:
def inplaceUpdate(f, inputs):
for i in range(len(inputs)):
inputs[i] = f(inputs[i])
# Define your inputs
x = 1
y = 2
z = 3
# Put them in a list so they can be mutated
inputs = [x, y, z]
# Define the function to apply
f = lambda i: i ** 2
# Call the function
inplaceUpdate(f, inputs)
# After calling, you can see that the list is updated
print(inputs) # Output: [1, 4, 9]
# If you want to update the individual variables, you can unpack the list back
x, y, z = inputs
print(x, y, z) # Output: 1 4 9
Explanation:
- Mutable container: We use a list
inputs
to holdx
,y
, andz
. Lists are mutable, so you can update their elements in place. - In-place modification: Inside the
inplaceUpdate
function, we iterate through the list and apply the functionf
to each element. - Unpacking: After modifying the list, you can unpack it back into individual variables if needed.
This way, you effectively update the values of x
, y
, and z
(via their container inputs
).
Alternative: Direct Assignment (not in-place)
If you don't need to modify the arguments in place but just want to return the updated values, you can directly assign the updated values:
def inplaceUpdate(f, x, y, z):
x = f(x)
y = f(y)
z = f(z)
return x, y, z
x, y, z = inplaceUpdate(f, x, y, z)
print(x, y, z) # Output: 1 4 9
In this case, you return the updated values and unpack them.
Let me know if this makes sense or if you'd like further clarification!