如何在Python中有效地将相同的操作应用于多个变量?

时间:2014-12-09 04:02:33

标签: python scope

我想做以下事情:

x = 1
y = 2
z = 3

l = [x,y,z]

for variable in l:
    variable += 2

print x
print y
print z

不幸的是,当我在此块之后打印x,y和z时,值分别保持在1,2和3。

我查看了this相关问题,但那里的解决方案并没有解决我的问题。

是否有一种简洁有效的方法对多个变量执行相同的操作,就像我上面尝试过的那样?

P.S。我使用的是Python 2.6

8 个答案:

答案 0 :(得分:9)

你不能像这样改变x,y,z。 x,y,z是整数,它们是不可变的。你需要制作新的变量。

x, y, z = (v + 2 for v in l)

答案 1 :(得分:2)

问题是variable的范围是for循环。

如果你要写

for variable in my_list:
    variable += 2
    print variable

你会看到你期望的价值。但是,一旦进入下一个for循环迭代,变量将被遗忘并替换为下一个列表值。

您想要做的是:

for i in range(len(my_list)):
   list[i] += 2

会产生你想要的效果。这是因为它是列表中的实际项目增加2,而不是for循环中的本地副本。

答案 2 :(得分:1)

查看map

x = 1
y = 2
z = 3

l = [x,y,z]

l = map(lambda x: x+2, l)  # [3, 4, 5]

你基本上是"映射"一个列表到另一个列表,修改了lambda函数定义的每个元素。

答案 3 :(得分:1)

您可以使用列表推导尝试类似下面的内容,然后将返回的值分配给变量xyz

>>> x = 1
>>> y = 2
>>> z = 3
>>> lst = [x,y,z]
>>> [i+2 for i in lst]
[3, 4, 5]
>>> x, y, z = [i+2 for i in lst]
>>> x
3
>>> y
4
>>> z
5

如下面的评论中所述,请勿使用list作为变量名称。 list是用于创建列表的特殊函数。

答案 4 :(得分:1)

您可以使用列表理解:

 print [variable+2 for variable in list]

'可变'在你的情况下是局部变量,一旦你退出for循环,它的范围就会减少。最好避免列表名称为list,因为它是内置的

答案 5 :(得分:1)

通常最好将一堆你想要操作的东西存储在列表中

xyz = [1, 2, 3]

for i in range(len(xyz)):
    xyz[i] += 2

有时(但你应该首先寻找其他方法)exec是好的(但如果你在用户的控制下执行输入,要小心)

>>> x = 1
>>> y = 2
>>> z = 3
>>> for variable in ['x', 'y', 'z']:
...     exec '{} += 2'.format(variable)
... 
>>> x, y, z
(3, 4, 5)

答案 6 :(得分:1)

我还没有看到答案提及可变性不变性,这是为什么你看到这个行为。它在Python中是一个非常重要的概念,因为它取代了"通过引用传递的概念" "传递价值"其他语言有。请参阅the documentation进行深入处理,但我会在此提供一个快速说明性示例。

在Python中,int是不可变的。这意味着无法更改整数的。另一方面,listdict是可变的,这意味着它们可以被更改。

考虑以下两种情况:

x = (1,2,3,4,5)

for y in x:
    y += 1

print x

打印:

(1, 2, 3, 4, 5)

这里我们尝试更新int s,它们是不可变的。因此,在for - 循环之后,x保持不变。您可以认为在循环的每次迭代中,x的当前条目被复制y,并且此副本被更改,而不是条目本身。现在让我们改变一个可变类型:

x = ([1], [2], [3], [4], [5])

for y in x:
    y += [42]

print x

打印:

([1, 42], [2, 42], [3, 42], [4, 42], [5, 42])

我们发现x 的元素已经更改了。这正是因为x的元素是列表,列表是可变的。

顺便说一句,您可能会注意到在两种情况下使用的容器都是一个元组,它是不可变的。你可以在元组中改变可变对象 - 没有问题 - 你只是不能改变元组本身及其包含的引用。

在完成所有这些之后,我仍然没有真正回答你的问题,但上面提到的答案是:你不应该单独存储这些对象,而是列在一个列表中。然后,给出的所有列表理解答案都是有意义的,并按照您的期望行事。

答案 7 :(得分:0)

目前尚不清楚是否要更改X,Y和Z的值或列表的内容。所以这里有一些选择:

# as pointed out by the comments this is a bad idea. It violates Pythonic principles
# and your outcomes may be less consistent than you would like
f = locals()
for n in ['x','y','z']:
    f[n] += 2 # modifies the values of the variables

您还可能尝试获取包含所有更新值的新列表。对于那个使用地图:

l = map(lambda x: x+2, [x,y,z])
'''
you could also do: 
    l = [x,y,z]
    l = map(lambda x: x+2, l)
'''

或者,您可能正在尝试更新l列表的值:

l = [x,y,z]
for idx, val in enumerate(l):
    l[idx] = val + 2