简体   繁体   English

在Python中通过引用修改变量列表的优雅方法?

[英]Elegant way to modify a list of variables by reference in Python?

Let's say I have a function f() that takes a list and returns a mutation of that list. 假设我有一个函数f(),它接受一个列表并返回该列表的变异。 If I want to apply that function to five member variables in my class instance (i), I can do this: 如果我想将该函数应用于我的类实例(i)中的五个成员变量,我可以这样做:

for x in [i.a, i.b, i.c, i.d, i.e]:
    x[:] = f(x)

1) Is there a more elegant way? 1)有更优雅的方式吗? I don't want f() to modify the passed list. 我不希望f()修改传递的列表。

2) If my variables hold a simple integer (which won't work with the slice notation), is there also a way? 2)如果我的变量包含一个简单的整数(对于切片表示法不起作用),还有一种方法吗? (f() would also take & return an integer in this case) (f()也会在这种情况下取​​一个整数)

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. Python没有通过引用传递。 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? 也许如果你要澄清你的具体任务,我们可以提出一个Python允许的解决方案?

Ultimately, what you want to do is incompatible with the way that Python is structured. 最终,您想要做的是与Python的结构方式不兼容。 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. 这是因为Python中不存在变量 References do. 参考文献 So ix is not a list, it is a reference to a list . 所以ix不是列表,它是对列表引用 Likewise, if it references a number. 同样,如果它引用了一个数字。 So if ix references y , then ix = z doesn't actually change the value y , it changes the location in memory that ix points to. 因此,如果ix引用y ,则ix = z实际上不会更改值y ,它会更改ix指向的内存中的位置。

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. 在python中,值是基本的,“变量”只是挂在特定值上的标记。 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. 在数字的情况下,没有办法做到这一点,因为数字是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. 如果您知道或可以确定属性的名称,则可以使用setattr进行修改,但这不会更改可能已存在的其他引用

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. 正如Rafe Kettler所说,如果你能更具体地了解你真正想做的事情,那么我们可以提出一种简单优雅的方式来做到这一点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM