所以,我的一个朋友问我的python编程是怎么来的;我说我学到了很多,而且很顺利。然后我的朋友,一个数学势利者问我:
“您是否可以在不使用第三个变量作为临时占位符的情况下交换2个变量的值?”
答案 0 :(得分:23)
在Python 中交换两个变量的规范方法是
a, b = b, a
请注意,无论a
或b
的“类型”是什么(数字,字符串,元组,对象,...),这都是有效的。当然,如果两个变量都引用不同类型的值,它也会起作用。
与许多命令式语言一样,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)
一个看似简单的问题。回想起来,大概是为了确定你是否在数学上思考。我思索过,这不是一个简单的问题,但并非遥不可及。
正如研究表明,这是一个相当常见的问题,有许多good和bad答案。我相信我找到了一个说明性的解决方案:
#!/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