一尘不染

python a,b = b,一个实现?它与C ++交换函数有何不同?

algorithm

当我想尝试以下版本的python版本时遇到了这个问题:https : //leetcode.com/problems/first-missing-
positive/discuss/17071/My-
short-c++-solution-O(
1)-space- and -准时

我不确定为什么a[0], a[a[0]] = a[a[0]], a[0]不进行交换?

>>> nums
[2, 1, 0]
>>> a = [2,1,0]
>>> a[0], a[a[0]] = a[a[0]], a[0]
>>> a
[2, 1, 0]
>>> a[0]
2
>>> a[0],a[2] = a[2], a[0]
>>> a
[0, 1, 2]

我的猜测是a,b = b的实现,语法类似于:

tmp = a[0] (tmp = 2)
a[0]  = a[a[0]] (a[0] = a[2] = 0)
a[a[0]] = tmp (a[a[0]] = a[0] = tmp = 2)

然后,我检查了C 中swap函数的实现。我对C
一无所知,但是看起来这个想法是一样的:http
:
//www.cplusplus.com/reference/algorithm/swap/

The behavior of these function templates is equivalent to:
template <class T> void swap (T& a, T& b)
{
  T c(std::move(a)); a=std::move(b); b=std::move(c);
}
template <class T, size_t N> void swap (T (&a)[N], T (&b)[N])
{
  for (size_t i = 0; i<N; ++i) swap (a[i],b[i]);
}

我们有c = a,然后a = b和b = a那么,为什么C ++交换函数没有这个问题?以及如何以pythonic方式编写这种交换函数?


阅读 347

收藏
2020-07-28

共1个答案

一尘不染

这种行为确实与Python评估类型的表达式的方式有关

a,b=b,a

实际上,Python要做的是首先通过创建元组“准备”右侧的值(b,a)。然后,将该元组解压缩并以相反的顺序分配给变量。

重要的是要注意,尽管Python使用对对象的 引用
,但变量名称所引用对象如果引用不可变类型的值,则可能会更改可变 类型并非如此(通过Python
FAQ中的示例进行
说明)。

要使用您使用的可变类型(列表)分解示例:

a = [2,1,0]    
a[0], a[a[0]] = a[a[0]], a[0]
  1. a[a[0]]从取值a[0]元件(等于2)列表a(值0)。
  2. a[0]2因此元组创建的(0,2)
  3. 元组(0,2)已解压缩,并在列表中0替换2(第0个元素)。
  4. 现在,a[a[0]]可以读取为:取list的第0个元素a(当前为0),然后用2tuple unpacking 0替换该位置处列表中的值(现在由2- 代替,这使操作看起来对列表没有任何作用) )。

如答案中vonOak所建议的那样,更改顺序会有所帮助,因为从上述第4点开始的步骤不会再次替换该值。

2020-07-28