[英]How do you apply the same action to multiple variables efficiently in Python?
我想做类似以下的事情:
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。
我看过这个相关的问题,但那里的解决方案并没有解决我的问题。
是否有一种简洁有效的方法对多个变量执行相同的操作,就像我上面尝试过的那样?
PS我正在使用Python 2.6
你不能像这样改变x,y,z。 x,y,z是整数,它们是不可变的。 你需要制作新的变量。
x, y, z = (v + 2 for v in l)
问题是variable
的范围是for
循环。
如果你要写
for variable in my_list:
variable += 2
print variable
你会看到你期望的价值观。 但是,一旦你进入下一个for
循环迭代,变量就会被遗忘并替换为下一个列表值。
你想要做的是:
for i in range(len(my_list)):
list[i] += 2
这将产生你想要的效果。 这是因为它是列表中的实际项目增加2,而不是for循环中的本地副本。
看看map
。
x = 1
y = 2
z = 3
l = [x,y,z]
l = map(lambda x: x+2, l) # [3, 4, 5]
您实际上是将一个列表“映射”到另一个列表,并修改了lambda函数定义的每个元素。
您可以使用列表推导尝试类似下面的内容,然后将返回的值分配给变量x
, y
, z
>>> 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
是一个用于创建列表的特殊函数。
你可以使用列表理解:
print [variable+2 for variable in list]
在您的情况下,'variable'是局部变量,一旦退出for循环,它的范围就会缩小。 最好避免列表名称作为list
因为它是内置的
通常最好将要操作的一堆东西存储在列表中
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)
我还没有看到答案提到可变性与不变性 ,这就是为什么你会看到这种行为。 这是Python中一个非常重要的概念,因为它取代了其他语言所具有的“按引用传递”和“按值传递”的概念。 请参阅文档以获得深入的处理,但我将在此处给出一个快速说明的示例。
在Python中, int
是不可变的。 这意味着无法更改整数的值 。 另一方面, list
s和dict
是可变的,这意味着它们可以被更改。
考虑这两种情况:
x = (1,2,3,4,5)
for y in x:
y += 1
print x
这打印:
(1, 2, 3, 4, 5)
这里我们尝试更新int
,这是不可变的。 因此在for
-loop之后, 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
的元素是列表,列表是可变的。
顺便说一句,你可能会注意到在两种情况下使用的容器都是一个元组,它是不可变的。 你可以在元组中改变可变对象 - 没有问题 - 你只是不能改变元组本身及其包含的引用。
在完成所有这些之后,我仍然没有真正回答你的问题,但上面暗示的答案是:你不应该单独存储这些对象,而应该在列表中。 然后给出所有列表理解答案都有意义,并做你期望的事情。
目前尚不清楚是否要更改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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.