Elegant way to modify a list of variables by reference in Python?
Let's say I have a function f() t开发者_Go百科hat takes a list and returns a mutation of that list. If I want to apply that function to five member variables in my class instance (i), I can do this:
for x in [i.a, i.b, i.c, i.d, i.e]:
x[:] = f(x)
1) Is there a more elegant way? I don't want f() to modify the passed list.
2) If my variables hold a simple integer (which won't work with the slice notation), is there also a way? (f() would also take & return an integer in this case)
Another solution, though it's probably not elegant:
for x in ['a', 'b', 'c', 'd', 'e']:
setattr(i, x, f(getattr(i, x)))
Python doesn't have pass by reference. The best you can do is write a function which constructs a new list and assign the result of the function to the original list. Example:
def double_list(x):
return [item * 2 for item in x]
nums = [1, 2, 3, 4]
nums = double_list(nums) # now [2, 4, 6, 8]
Or better yet:
nums = map(lambda x: x * 2, nums)
Super simple example, but you get the idea. If you want to change a list from a function you'll have to return the altered list and assign that to the original.
You might be able to hack up a solution, but it's best just to do it the normal way.
EDIT
It occurs to me that I don't actually know what you're trying to do, specifically. Perhaps if you were to clarify your specific task we could come up with a solution that Python will permit?
Ultimately, what you want to do is incompatible with the way that Python is structured. You have the most elegant way to do it already in the case that your variables are lists but this is not possible with numbers.
This is because variables do not exist in Python. References do. So i.x
is not a list, it is a reference to a list. Likewise, if it references a number. So if i.x
references y
, then i.x = z
doesn't actually change the value y
, it changes the location in memory that i.x
points to.
Most of the time, variables are viewed as boxes that hold a value. The name is on the box. In python, values are fundamental and "variables" are just tags that get hung on a particular value. It's very nice once you get used to it.
In the case of a list, you can use use slice assignment, as you are already doing. This will allow all references to the list to see the changes because you are changing the list object itself. In the case of a number, there is no way to do that because numbers are immutable objects in Python. This makes sense. Five is five and there's not much that you can do to change it. If you know or can determine the name of the attribute, then you can use setattr
to modify it but this will not change other references that might already exist.
As Rafe Kettler says, if you can be more specific about what you actually want to do, then we can come up with a simple elegant way to do it.
精彩评论