在不使用第三个变量的情况下交换 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 05:19:32  来源:igfitidea点击:

Swap 2 values of 2 variables without using a third variable; python

pythonfunctionmathportability

提问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 aor bis (numeric, string, tuple, object, ...). Of course, it works too if both variables reference values of different types.

请注意,无论aor的“类型”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,分别具有ab 的起始值。执行以下赋值(结果变量的值显示为注释):

(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.

一种在不使用第三个变量的情况下交换值的规范方法。