Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中是否有交换两个变量的标准化方法?_Python_Syntax_Swap_Conventions - Fatal编程技术网

Python中是否有交换两个变量的标准化方法?

Python中是否有交换两个变量的标准化方法?,python,syntax,swap,conventions,Python,Syntax,Swap,Conventions,在Python中,我看到两个变量值使用以下语法交换: left, right = right, left 这被认为是交换两个变量值的标准方法,还是有其他方法,按照惯例,两个变量最常交换?这是交换两个变量的标准方法,是的 Python从左到右计算表达式。注意 在评估作业时,右手边在 左手边 这意味着表达式a,b=b,a如下所示: 计算右侧b,a,也就是说,在内存中创建两个元素的元组。这两个元素是由标识符b和a指定的对象,它们在程序执行期间遇到指令之前存在。 在创建这个元组之后,还没有对这个元组对

在Python中,我看到两个变量值使用以下语法交换:

left, right = right, left

这被认为是交换两个变量值的标准方法,还是有其他方法,按照惯例,两个变量最常交换?

这是交换两个变量的标准方法,是的

Python从左到右计算表达式。注意 在评估作业时,右手边在 左手边

这意味着表达式a,b=b,a如下所示:

计算右侧b,a,也就是说,在内存中创建两个元素的元组。这两个元素是由标识符b和a指定的对象,它们在程序执行期间遇到指令之前存在。 在创建这个元组之后,还没有对这个元组对象进行赋值,但这并不重要,Python内部知道它在哪里。 然后,计算左侧,也就是说,将元组分配给左侧。 由于左侧由两个标识符组成,因此对元组进行解包,以便将第一标识符a分配给元组的第一个元素,该元素是交换之前的对象b,因为它具有名称b 并且第二标识符b被分配给元组的第二元素,该元组是在交换之前是a的对象,因为其标识符是a 该机制有效地交换了分配给标识符a和b的对象

所以,回答你的问题:是的,这是交换两个对象上的两个标识符的标准方法。
顺便说一下,对象不是变量,它们是对象。

我知道三种交换变量的方法,但是a,b=b,a是最简单的。有

整数的异或运算 x=x^y y=y^x x=x^y 或者简而言之

x ^= y
y ^= x
x ^= y
临时变量 w=x x=y y=w 德尔瓦 元组交换 x、 y=y,x
我不会说这是一种标准的交换方式,因为它会导致一些意想不到的错误

nums[i], nums[nums[i] - 1] = nums[nums[i] - 1], nums[i]

nums[i]将首先修改,然后影响第二个变量nums[nums[i]-1]。

不适用于多维数组,因为此处使用引用

import numpy as np

# swaps
data = np.random.random(2)
print(data)
data[0], data[1] = data[1], data[0]
print(data)

# does not swap
data = np.random.random((2, 2))
print(data)
data[0], data[1] = data[1], data[0]
print(data)

另请参见

要解决所解释的问题,可以使用copy模块通过以下函数返回包含值的反向副本的元组:

from copy import copy

def swapper(x, y):
  return (copy(y), copy(x))
与lambda相同的功能:

然后,将这些名称指定给所需的名称,如下所示:

x, y = swapper(y, x)
注意:如果愿意,您可以导入/使用deepcopy而不是copy。

您可以组合元组和异或交换:x,y=x^x^y,x^y^y

使用lambda:

输出:

Before swapping: x =  10 , y =  20
After swapping: x =  20 , y =  10

是最简单也是唯一一个没有混淆的。XOR不交换变量。它交换整数变量。或者其他一些类型正确地实现了XOR运算符。此外,根据Rogalski的回答,元组交换在解释器中得到了优化,因此没有什么反对它的。使用+-运算符可以避免XOR问题,但我觉得最好的方法是a,b=b,a代码x=x+y=x-y x=x-y代码如果是关于整数值的,你可以用简单的算术来解决这个问题。在几乎任何编程语言中,如果a依赖于b,使用swapa,b是不安全的,反之亦然。例如,swapa,b可以扩展为:var c=a,a=b,b=c。然后,最后的赋值将使用a的新值来计算b.nums[nums[i]-1],nums[i]=nums[i],nums[nums[i]-1]的地址。将解决问题。@JacksonKelley右侧的评估是安全的。在nums[i]中,nums[nums[i]-1]=nums[nums[i]-1],nums[i]:问题是当python执行左侧赋值时,nums[i]被更改,这导致nums[nums[i]-1发生意外更改。你可以想象一开始你想要nums[1],nums[2]=nums[2],nums[1],但是在运行nums[1]=nums[2]之后,你不再有nums[2]=nums[1],而是有nums[888]=nums[1]。这确实是numpy库的一个特殊功能或bug。@eyquem:这只是归结为是否由语言为元组/列表赋值定义的。Python确实是这样,大多数老语言都没有.HMM MM有SavaP[i],[k]为什么我们不能为Python这样的东西。@ NILS因为在Python中,赋值是一个别名操作,而C++ C++中的赋值是一个替换操作。因此,在Python中,不能将传递给函数的参数值替换为C++中的函数,只能对它们进行突变。关于这些术语的解释,请参见Grogono和Sakkinen。据我所知,以这种方式交换两个变量不会占用额外的内存,只会占用两个变量本身的内存,对吗?@Catbuilts构造元组会占用一些额外的内存,可能比交换的三变量版本占用的内存要多,但是由于交换的只是内存地址,所以从绝对意义上讲,不会有太多额外的内存
可能会有24个额外字节。@Brilliand:Thks。你有这方面的文件吗。这本书很有趣,我想再读一读。谢谢。@ CasBueStudio我不确定,但它可能有助于阅读C++指针如何工作。而Python尝试自动为你做最好的事情,C++实际上给你所有的选择来做所有可能的正确和错误的方式,所以这是一个很好的起点,学习Python所采取的方法的缺点。还要记住,拥有一个64位操作系统意味着存储一个内存地址需要占用64位内存——这也是我得到24字节数字的部分原因。很好的解释。这就是为什么你也可以用这个方法来重新排列任意数量的变量,例如a,b,c=c,a,b。你试图通过复制来解决什么问题?中讨论的问题。但它没有说明任何问题,事实上他说是的,这是交换两个标识符的标准方法
x, y = 10, 20

print('Before swapping: x = %s, y = %s '%(x,y))

x, y = x ^ x ^ y, x ^ y ^ y

print('After swapping: x = %s, y = %s '%(x,y))
x, y = 10, 20

print('Before swapping: x = %s, y = %s '%(x,y))

print('After swapping: x = %s, y = %s '%(x ^ x ^ y, x ^ y ^ y))
x, y = 10, 20

print('Before swapping: x = %s, y = %s' % (x, y))

swapper = lambda x, y : ((x ^ x ^ y), (x ^ y ^ y))

print('After swapping: x = %s, y = %s ' % swapper(x, y))
Before swapping: x =  10 , y =  20
After swapping: x =  20 , y =  10