在不使用第三个变量的情况下交换 2 个变量的 2 个值;Python
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/24844487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Swap 2 values of 2 variables without using a third variable; python
提问by todd_dsm
So, a friend of mine asked how my python programming was coming; I said I was learning a lot and that it was coming along nicely. Then my friend, a math-snob, asks me:
所以,我的一个朋友问我的 Python 编程是怎么来的;我说我学到了很多东西,而且进展顺利。然后我的数学势利朋友问我:
"Can you swap the value of 2 variables without using a third variable as a temporary placeholder?"
“你能在不使用第三个变量作为临时占位符的情况下交换 2 个变量的值吗?”
回答by todd_dsm
A seemingly simple question. In retrospect, presumably designed to determine whether or not you think mathematically. I pondered, it's not a simple problem but not out of reach.
一个看似简单的问题。回想起来,大概是为了确定您是否进行数学思考。我想了想,这不是一个简单的问题,但也不是遥不可及。
As research reveals this is a fairly common question with many goodand badanswers. I believe I've found an illustrative solution:
研究表明,这是一个相当普遍的问题,有许多好的和坏的答案。我相信我找到了一个说明性的解决方案:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# MODULES
# VARIABLES
x = 20
y = 10
# FUNCTIONS
# Swap 2 vars: longhand method, the portable way:
def swapNosL(val1, val2):
print("BEFOR: val1: %r, val2: %r") % (val1, val2)
val1 = val1 + val2
val2 = val1 - val2
val1 = val1 - val2
print("AFTER: val1: %r, val2: %r") % (val1, val2)
return(val1, val2)
# Swap 2 vars: shorthand method, the non/less-portable way:
def swapNosC(val1, val2):
print("BEFOR: val1: %r and val2: %r") % (val1, val2)
val1, val2 = val2, val1
print("AFTER: val1: %r and val2: %r") % (val1, val2)
return(val1, val2)
# MAIN PROGRAM
print("")
print("The Problem:")
print("We need to swap 2 variables without using a 3rd.")
print("The values: 'x' is %r and 'y' is %r.") % (x, y)
print("")
(retVal1, retVal2) = swapNosC(x, y)
print("")
print("Now values: 'x' is %r and 'y' is %r.") % (retVal1, retVal2)
print"\n"
While there is some unnecessary repetition, the logic is solid. To baseline:
虽然有一些不必要的重复,但逻辑是可靠的。基线:
1) It works with all integers both positive and negative; I haven't tested floats yet.
1) 它适用于所有正整数和负整数;我还没有测试浮动。
2) The same memory is used 1 way or the other; only 2 variables are used either way.
2)以一种方式或另一种方式使用相同的内存;无论哪种方式,都只使用 2 个变量。
3) Portability is (or should) always be a goal. In the case that programming languages go away and you need to port to a new one, research indicates that handling this problem mathematically will allow for greater portability.
3)可移植性是(或应该)始终是一个目标。在编程语言消失而您需要移植到新语言的情况下,研究表明以数学方式处理这个问题将允许更大的可移植性。
In the "bad" example, this method is language-specific and porting to a language would (some day) require a different solution. I hope Python never goes the way of COBOL but the future is a big place.
在“坏”的例子中,这种方法是特定于语言的,移植到一种语言(有一天)需要不同的解决方案。我希望 Python 永远不会走 COBOL 的道路,但未来是一个很大的地方。
However, in the "good" example the math is handled in a similar way in the C language. In fact, research also indicates math is generallyhandled the same way in most languages.
但是,在“好”示例中,数学在 C 语言中以类似的方式处理。事实上,研究还表明数学在大多数语言中通常以相同的方式处理。
Therefore leaving the math in tact and only negotiating the syntax modification is the more portable method.
因此,让数学保持原状,只协商语法修改是更便携的方法。
At some point I will concede to my friend that this was a good learning opportunity for me. But not for a while. I found the answer but failed by cheating with research.
在某些时候,我会向我的朋友承认,这对我来说是一个很好的学习机会。但不是一段时间。我找到了答案,但因研究作弊而失败。
TT
TT
回答by Sylvain Leroux
The canonical way to swap two variables in Pythonis
在 Python 中交换两个变量的规范方法是
a, b = b, a
Please note than this is valid whatever the "type" of a
or b
is (numeric, string, tuple, object, ...). Of course, it works too if both variables reference values of different types.
请注意,无论a
or的“类型”b
是什么(数字、字符串、元组、对象等),这都是有效的。当然,如果两个变量都引用不同类型的值,它也可以工作。
As many imperative languages, Python evaluates assignments right to left. Conceptuallyall behave likeif a tuple was build for the right hand part of the expression, and then deconstructedto perform the affectation to the left hand part. This has already been explained more clearly than I can here: https://stackoverflow.com/a/14836456/2363712
与许多命令式语言一样,Python 从右到左计算赋值。从概念上讲,所有的行为都像是为表达式的右手部分构建了一个元组,然后解构以对左手部分执行假动作。这已经比我在这里解释得更清楚了:https: //stackoverflow.com/a/14836456/2363712
The real details are implementation dependent though. For example, to build on a comment by @undefined is not a functionbelow, the CPython virtual machine has a ROT_TWOopcode that swap the two top-level items on the stack, and so allow to optimize such affectation. See this previous answer for a detailed explanation: https://stackoverflow.com/a/21047622/2363712
不过,真正的细节取决于实现。例如,基于@undefined的注释不是下面的函数,CPython 虚拟机有一个ROT_TWO操作码,可以交换堆栈上的两个顶级项目,因此可以优化这种影响。有关详细说明,请参阅上一个答案:https: //stackoverflow.com/a/21047622/2363712
回答by afeldspar
If your friend is a "math-snob", he may have in mind a particular trick, which you can use in languages where you can apply the XOR function to the bitstring representation of numbers.
如果你的朋友是一个“数学势利小人”,他可能想到了一个特殊的技巧,你可以在语言中使用它,你可以将 XOR 函数应用于数字的位串表示。
Say we have variables X and Y, with starting values of aand brespectively. Perform the following assignments (the values of the variables which result are shown as comments):
假设我们有变量 X 和 Y,分别具有a和b 的起始值。执行以下赋值(结果变量的值显示为注释):
(start) # X == a; Y == b
X = X XOR Y # X == a XOR b; Y == b
Y = X XOR Y # X == a XOR b; Y == b XOR (a XOR b)
X = X XOR Y # X == (a XOR b) XOR b XOR (a XOR b); Y == b XOR (a XOR b)
Because XOR is associative, we can regroup the resulting equations as follows:
因为 XOR 是关联的,我们可以将结果方程重新组合如下:
X == (a XOR a) XOR (b XOR b) XOR b
Y == (b XOR b) XOR a
Because xXOR x== 0 and xXOR 0 == x, we can simply remove all those pairs of variables XOR'ed with themselves, and what's left is:
因为xXOR x== 0 和xXOR 0 == x,我们可以简单地删除所有那些与自身异或的变量对,剩下的是:
X == b
Y == a
which is what we wanted, to switch the values without using a third variable.
这就是我们想要的,在不使用第三个变量的情况下切换值。
It's been quite a while since I did any bit manipulation in Python, so I cannot tell you whether this trick works in Python, but there are languages where it works. I also can't tell you whether it actually has sufficient benefits to balance out its non-obviousness.
我已经有一段时间没有在 Python 中进行任何操作了,所以我不能告诉你这个技巧在 Python 中是否有效,但是在某些语言中它是有效的。我也不能告诉你它是否真的有足够的好处来平衡它的非显而易见性。
回答by Gokul Kurup
x = x + y; // x now becomes 15
y = x - y; // y becomes 10
x = x - y; // x becomes 5
This is the main snippet of code This is what you friend meant
这是代码的主要片段 这就是你朋友的意思
回答by Krutarth Gor
you can directly try for,
你可以直接尝试,
a, b = b, a
A canonical way to exchange the value without using third variable.
一种在不使用第三个变量的情况下交换值的规范方法。