在不使用第三个变量的情况下交换2个变量的2个值;蟒蛇

时间:2014-07-19 20:05:52

标签: python function math portability

所以,我的一个朋友问我的python编程是怎么来的;我说我学到了很多,而且很顺利。然后我的朋友,一个数学势利者问我:

“您是否可以在不使用第三个变量作为临时占位符的情况下交换2个变量的值?”

5 个答案:

答案 0 :(得分:23)

在Python 中交换两个变量的规范方法是

a, b = b, a

请注意,无论ab的“类型”是什么(数字,字符串,元组,对象,...),这都是有效的。当然,如果两个变量都引用不同类型的值,它也会起作用。


与许多命令式语言一样,Python从右到左评估分配。 概念如果为表达式的右手部分构建元组,然后解构以执行左手的做法,则所有行为都像一样部分。这已经比我在这里更清楚地解释了:https://stackoverflow.com/a/14836456/2363712

但真正的细节依赖于实现。例如,要在@undefined is not a function下构建注释,CPython虚拟机有一个ROT_TWO操作码,可以交换堆栈中的两个顶级项目,因此可以优化这种做法。有关详细说明,请参阅此前一个答案:https://stackoverflow.com/a/21047622/2363712

答案 1 :(得分:4)

 x = x + y;  // x now becomes 15
 y = x - y;  // y becomes 10
 x = x - y;  // x becomes 5

这是代码的主要代码段 这就是你朋友的意思

答案 2 :(得分:1)

如果你的朋友是" math-snob",他可能会想到一个特殊的技巧,你可以在可以将XOR函数应用于数字的位串表示的语言中使用。

假设我们有变量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)

因为XOR是关联的,我们可以按如下方式对得到的方程重新组合:

X == (a XOR a) XOR (b XOR b) XOR b
Y == (b XOR b) XOR a

因为 x XOR x == 0且 x XOR 0 == x ,我们只需删除所有这些变量对与他们自己进行了异或,以及剩下的是:

X == b
Y == a

这就是我们想要的,在不使用第三个变量的情况下切换值。

自从我在Python中进行任何操作以来已经有一段时间了,所以我不能告诉你这个技巧是否适用于Python,但有些语言可以运行。我也无法告诉你它是否真的有足够的好处来平衡它的非显而易见性。

答案 3 :(得分:1)

你可以直接尝试,

a, b = b, a

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

答案 4 :(得分:-5)

一个看似简单的问题。回想起来,大概是为了确定你是否在数学上思考。我思索过,这不是一个简单的问题,但并非遥不可及。

正如研究表明,这是一个相当常见的问题,有许多goodbad答案。我相信我找到了一个说明性的解决方案:

#!/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"

虽然有一些不必要的重复,但逻辑是可靠的。基线:

1)它适用于所有正面和负面的整数;我还没有测试漂浮物。

2)相同的内存以1种方式使用;只使用两个变量。

3)便携性是(或应该)始终是一个目标。如果编程语言消失并且你需要移植到新的编程语言,研究表明以数学方式处理这个问题将允许更大的可移植性。

在"坏"例如,此方法是特定于语言的,并且移植到某种语言(某天)需要不同的解决方案。我希望Python永远不会走COBOL的道路,但未来是一个很大的地方。

然而,在" good"例如,数学在C语言中以类似的方式处理。事实上,研究还表明,在大多数语言中,数学通常以相同的方式处理。

因此,将数学留在机智中并且仅协商语法修改是更便携的方法。

在某些时候,我会向我的朋友承认,这对我来说是一个很好的学习机会。但不是一段时间。我找到了答案却因为研究作弊而失败了。

TT