简体   繁体   English

使用XOR运算符交换数组在Python中不起作用

[英]Swapping array with the XOR operator doesn’t work in Python

I was trying to code Quicksort in Python (see the full code at the end of the question) and in the partition function I am supposed to swap two elements of an array (call it x ). 我试图在Python中编写Quicksort代码(请参阅问题末尾的完整代码),在分区函数中,我应该交换数组的两个元素(称为x )。 I am using the following code for swapping based on the xor operator: 我使用以下代码进行基于xor运算符的交换:

x[i]^=x[j]
x[j]^=x[i]
x[i]^=x[j]

I know that it should work because of the nilpotence of the xor operator (ie x^x=0 ) and I have done it like a million times in Java and in C without any problem. 我知道它应该工作,因为xor运算符的nilpotence(即x^x=0 ),我已经在Java和C中完成了一百万次而没有任何问题。 My question is: why doesn't it work in Python? 我的问题是:为什么它在Python中不起作用? It seems that it is not working when x[i] == x[j] (maybe i = j ?). x[i] == x[j] (也许i = j ?)时,它似乎不起作用。

x = [2,4,3,5,2,5,46,2,5,6,2,5]
print x
def part(a,b):
  global x
  i = a
  for j in range(a,b):
    if x[j]<=x[b]:
      x[i]^=x[j]#t = x[i]
      x[j]^=x[i]#x[i] = x[j]
      x[i]^=x[j]#x[j]=t
      i = i+1
  r = x[i]
  x[i]=x[b]
  x[b]=r
  return i
def quick(y,z):
  if z-y<=0:
    return
  p = part(y,z)
  quick(y,p-1)
  quick(p+1,z)
quick(0,len(x)-1)
print x

As to why it doesn't work, it really shouldn't matter 1 , because you shouldn't be using code like that in the first place, especially when Python gives you a perfectly good 'atomic swap' capability: 至于为什么它不起作用,它真的应该不重要1 ,因为你不应该首先使用这样的代码, 特别是当Python给你一个非常好的'原子交换'功能时:

x[i], x[j] = x[j], x[i]

It's always been my opinion that all programs should be initially optimised for readability first and only have performance or storage improvements imposed if there's a clear need and a clear benefit (neither of which I've ever seen for the XOR trick outside some incredibly small data environments like some embedded systems). 我一直认为所有程序最初都应该首先针对可读性进行优化,只有在明确需要和明显优势的情况下才能实现性能或存储改进(在一些非常小的数据之外,我从未见过XOR技巧)环境就像一些嵌入式系统)。

Even in languages that don't provide that nifty feature, it's more readable and probably faster to use a temporary variable: 即使在提供这种漂亮功能的语言中,使用临时变量也更具可读性并且可能更快:

tmp = x[i]
x[i] = x[j]
x[j] = tmp

1 However, if you really want to know why it's not working, it's because that trick is okay for swapping two distinct variables, but not so well when you use it with the same variable, which is what you'll be doing when you try to swap x[i] with x[j] when i is equal to j . 1然而,如果你真的想知道为什么它不起作用,那是因为这个技巧可以交换两个不同的变量,但是当你使用同一个变量时不太好,这就是你在尝试时会做的事情当i等于j时,用x[j]交换x[i]

It's functionally equivalent to the following, with print statements added so you can see where the whole thing falls apart: 它在功能上等同于以下内容,添加了print语句,以便您可以看到整个事物分崩离析的地方:

>>> a = 42
>>> a ^= a ; print(a)
0
>>> a ^= a ; print(a)
0
>>> a ^= a ; print(a)
0

Contrast that with two distinct variables, which works okay: 对比两个不同的变量,哪个工作正常:

>>> a = 314159; b = 271828; print(a,b)
314159 271828

>>> a ^= b; print(a,b)
61179 271828

>>> b ^= a; print(a,b)
61179 314159

>>> a ^= b; print(a,b)
271828 314159

The problem is that the trick works by transferring information between the two variables gradually (similar to the fox/goose/beans puzzle). 问题是这个技巧的工作原理是逐渐在两个变量之间传递信息(类似于狐狸/鹅/豆之谜)。 When it's the same variable, the first step doesn't so much transfer information as it does destroy it. 当它是相同的变量时,第一步并没有那么多传递信息,因为它会破坏它。

Both Python's 'atomic swap' and use of a temporary variable will avoid this problem completely. Python的'原子交换'和临时变量的使用都将完全避免这个问题。

I was reviewing this fact, and for example, you could express the xor like the following expression: 我正在审查这个事实,例如,您可以像下面的表达式一样表达xor:

a xor b = (a or b) - (a & b)

So, basically, if you replace a by b, Whoa! 所以,基本上,如果你用b替换a,哇! xDD You'll get it, zero. xDD你会得到它,零。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM