繁体   English   中英

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

[英]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函数定义的每个元素。

您可以使用列表推导尝试类似下面的内容,然后将返回的值分配给变量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是一个用于创建列表的特殊函数。

你可以使用列表理解:

 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.

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