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

在Python中通过引用修改变量列表的优雅方式?,python,reference,Python,Reference,假设我有一个函数f(),它接受一个列表并返回该列表的一个变体。如果我想将该函数应用于我的类实例(I)中的五个成员变量,我可以这样做: for x in [i.a, i.b, i.c, i.d, i.e]: x[:] = f(x) 1) 还有更优雅的方式吗?我不希望f()修改传递的列表 2) 如果我的变量包含一个简单的整数(这在切片表示法中不起作用),还有其他方法吗?(在本例中,f()还将获取并返回一个整数)Python没有按引用传递。您最好编写一个函数来构造一个新列表,并将函数的结果分

假设我有一个函数f(),它接受一个列表并返回该列表的一个变体。如果我想将该函数应用于我的类实例(I)中的五个成员变量,我可以这样做:

for x in [i.a, i.b, i.c, i.d, i.e]:
    x[:] = f(x)
1) 还有更优雅的方式吗?我不希望f()修改传递的列表


2) 如果我的变量包含一个简单的整数(这在切片表示法中不起作用),还有其他方法吗?(在本例中,f()还将获取并返回一个整数)

Python没有按引用传递。您最好编写一个函数来构造一个新列表,并将函数的结果分配给原始列表。例如:

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]
或者更好:

nums = map(lambda x: x * 2, nums)
超级简单的例子,但你明白了。如果要更改函数中的列表,必须返回更改后的列表并将其分配给原始列表

你也许能找到一个解决方案,但最好是用正常的方式

编辑
我突然意识到我并不知道你到底想做什么,特别是。如果您要澄清您的具体任务,我们可能会提出一个Python允许的解决方案?

另一个解决方案,尽管它可能并不优雅:

for x in ['a', 'b', 'c', 'd', 'e']:
    setattr(i, x, f(getattr(i, x)))

最终,您想要做的与Python的结构方式不兼容。在变量是列表的情况下,您已经有了最优雅的方法来实现这一点,但对于数字来说,这是不可能的

这是因为Python中不存在变量。推荐信可以。因此,
i.x
不是一个列表,而是对列表的引用。同样,如果它引用了一个数字。因此,如果
i.x
引用了
y
,那么
i.x=z
实际上并没有改变值
y
,它会改变
i.x
指向的内存中的位置

大多数情况下,变量被视为包含值的框。名字在盒子上。在python中,值是基本的,“变量”只是挂在特定值上的标记。一旦你习惯了,它就很好了

在列表的情况下,您可以使用切片分配,就像您已经在做的那样。这将允许对列表的所有引用看到更改,因为您正在更改列表对象本身。对于数字,没有办法做到这一点,因为数字在Python中是不可变的对象。这是有道理的。五等于五,你没办法改变它。如果您知道或可以确定属性的名称,则可以使用
setattr
对其进行修改,但这不会更改可能已经存在的其他引用


正如Rafe Ketterr所说,如果你能更具体地说明你真正想做什么,那么我们可以想出一个简单而优雅的方法来做。

看起来
f
是用来获取一个列表的,但你也在对列表进行迭代。f获取的列表存储在i.a,i.b,示例中的迭代是在存储(引用,对于纯粹主义者)列表的变量上进行的。好的,实际上并没有覆盖变量,但这就是我要寻找的效果。这不会改变实际的列表对象,只是一个引用。@aaronasterling是的,您必须创建一个新列表(或分配给现有列表)。@aaronasterling那么我想他就走运了。我也想要一架直升机:在属性是列表的情况下,这不会有与切片分配相同的效果。虽然so+1,但它仍然尽可能接近所需。这正是我正在寻找的功能,尽管我希望它更具可读性。在我的情况下,我实际上更希望对列表的任何其他引用不受影响。所以setattr方法会做正确的事情(如Antoine的建议),但没有我想要的优雅。@David Well然后
setattr
是唯一的方法。当您现在使用切片分配时,其他引用将引用修改后的列表。我同意,不过很难看。更多关于您试图做什么的详细信息(这是一个更好的答案;)我的特殊应用是:我有一组成员变量,每个变量都有一个文件路径列表,可能需要全局扩展和一些其他字符串操作。My f()获取这样一个列表并返回全局版本。我想让这整组成员变量都经历这个过程。我想我可以把它们都放在自己的dict中以便于迭代,但这是现有的代码。@David,将它们放在字典中肯定是正确的方法。任何其他备选方案都需要您具体列举要更改的属性。