在Python中将多个返回值添加到多个变量中

4

赋值

我是 Python 的新手,但我已经学会了使用所谓的元组进行多个值的赋值和返回。

同时赋值多个值

> a, b = 1, 2
> a
1
> b
2

返回多个值

> def f():
>   return 3, 4
>
> f()
(3, 4)

两者的组合也可行

> c, d = f()
> c
3
> d
4

添加

可以使用重载运算符+=iadd)将返回值隐式地添加到变量中。

加法运算符+=(相应地称为iadd

> e = 5
> e += 5
> e
10

也适用于函数

> def g():
>   return 10
>
> e += g()
> e
20

问题

我是否正确,上述行为不能同时使用? 我尝试了下面的代码片段,但它对我无效。

> x, y = 1, 2
> x, y += 3, 4
SyntaxError: illegal expression for augmented assignment

> def z():
>   return 10, 100
> x, y += z()
SyntaxError: illegal expression for augmented assignment

直到现在,Python一直非常直观。这就是为什么我认为这种方法会立即奏效的原因。
为什么元组没有重载+=运算符?这难道不是保持Python尽可能简单的意义吗?
我找到了两种解决这个“问题”的方法(使用上面提到的x、y、z()):
> import operator
> t = x, y
> tuple(map(operator.add, t, z()))

或者简单点(使用上面的xyz()):

> x1, y1 = z()
> x += x1
> y += y1

除了我提到的方法,还有更好或更直观的方法吗?


4
为什么元组没有重载 += 运算符?由于元组是不可变的,对元组执行任何“添加”操作都没有太多意义。 - Łukasz Rogalski
@ŁukaszRogalski 但是既然xy都不是元组,那么我们要改变的是哪个元组呢? - Ma0
1
+= 对于 tuples 来说意味着类似于外推的操作,也就是求和形式的总和,如果 Python 将其视为合法表达式,那么我想这就是您期望的结果。 - Krishna Oza
这个StackOverflow答案提供了有关增强赋值的更多信息:https://dev59.com/W2Ml5IYBdhLWcg3wyJYe - cssko
2
就编程而言,对于这个问题的哲学回答是:它会在元组和列表之间创建一种不对称。 += 运算符已经对列表有了意义:它扩展了它们。如果 += 对于元组执行逐元素相加,那么行为将与列表不对称——列表只应该因其可变性而与元组不同。 - Arya McCarthy
@ŁukaszRogalski 字符串也是不可变的(至少在我最先学习的Java中是这样的)!它们重载了 + 运算符,只会创建一个新的不可变对象。此外,仅右侧的元组是不可变的,左侧的变量并非如此。 - winklerrr
2个回答

2
你是正确的,这两种方法不能同时使用,原因如下(据我所知):
在Python中,当你使用“=”运算符时,它会计算等号右侧的所有表达式,然后将其应用于左侧(这就是为什么你可以使用多重赋值技巧。有关此内容的更多信息,请阅读有关Python中的打包和解包的内容)。
当你使用“+=”运算符时,它会调用左侧对象上的“__iadd__”方法,并将右侧表达式作为参数进行评估。由于你不能将“iadd”添加到元组中,而只能添加到可变对象中(请阅读Python中的可变和不可变内容),因此此操作是不合法的。
你认为“x,y += x1,y1”操作应该执行的操作是“map”函数所做的:它逐个对每个元素执行操作。 你展示的另一种解决方案是我会做的方式。如果你之后需要“z()”的结果,这也很好。

2

我喜欢列表推导式。学习Python时,这绝对是你需要了解的东西:

def add_for_all(sum1, sum2):
  return [j+sum2[i] for i,j in enumerate(sum1)]

wx = [1,2]
yz = [3,4]

print (add_for_all(wx, yz))

好的,但我怀疑这个问题不是关于你如何做到这一点,而是为什么它不能按照 OP 尝试的方式工作。 - Ma0
我明白了。不知何故,包含问号的句子(例如“除了我提到的方法之外,是否有更好或更直观的方法?”)鼓励我发表意见。 - EvilSmurf
列表推导式非常有用,这也是我喜欢Python的许多原因之一!但对于我的特定用例来说,它似乎有点过度了。但你是对的:这是另一种可行的方法! - winklerrr

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接