在 Python 中反转数字的(二进制)数字的巧妙方法?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15180168/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 13:33:23  来源:igfitidea点击:

Slick way to reverse the (binary) digits of a number in Python?

pythonalgorithmbit-manipulation

提问by math4tots

I am looking for a slick function that reverses the digits of the binary representation of a number.

我正在寻找一个巧妙的函数来反转一个数字的二进制表示的数字。

If fwere such a function I would have

如果f是这样的功能,我会

int(reversed(s),2) == f(int(s,2))whenever s is a string of zeros and ones starting with 1.

int(reversed(s),2) == f(int(s,2))每当 s 是一串以 1 开头的 0 和 1 时。

Right now I am using lambda x: int(''.join(reversed(bin(x)[2:])),2)

现在我正在使用 lambda x: int(''.join(reversed(bin(x)[2:])),2)

which is ok as far as conciseness is concerned, but it seems like a pretty roundabout way of doing this.

就简洁性而言,这是可以的,但这样做似乎是一种非常迂回的方式。

I was wondering if there was a nicer (perhaps faster) way with bitwise operators and what not.

我想知道按位运算符是否有更好(也许更快)的方式,而没有。

采纳答案by arshajii

How about

怎么样

int('{0:b}'.format(n)[::-1], 2)

or

或者

int(bin(n)[:1:-1], 2)


The second method seems to be the faster of the two, however both are much faster than your current method:

第二种方法似乎是两者中更快的一种,但是两者都比您当前的方法快得多:

import timeit

print timeit.timeit("int('{0:b}'.format(n)[::-1], 2)", 'n = 123456')

print timeit.timeit("int(bin(n)[:1:-1], 2)", 'n = 123456')

print timeit.timeit("int(''.join(reversed(bin(n)[2:])),2)", 'n = 123456')
1.13251614571
0.710681915283
2.23476600647

回答by NPE

Here is my suggestion:

这是我的建议:

In [83]: int(''.join(bin(x)[:1:-1]), 2)
Out[83]: 9987

Same method, slightly simplified.

相同的方法,稍微简化。

回答by Gareth Latty

I would argue your current method is perfectly fine, but you can lose the list()call, as str.join()will accept any iterable:

我认为您当前的方法非常好,但您可能会失去list()调用,因为str.join()会接受任何迭代:

def binary_reverse(num):
    return int(''.join(reversed(bin(num)[2:])), 2)

It would also advise against using lambdafor anything but the simplest of functions, where it will only be used once, and makes surrounding code clearer by being inlined.

它还建议不要使用lambda最简单的函数以外的任何东西,它只会被使用一次,并通过内联使周围的代码更清晰。

The reason I feel this is fine as it describes what you want to do - take the binary representation of a number, reverse it, then get a number again. That makes this code very readable, and that should be a priority.

我觉得这很好,因为它描述了你想要做什么 - 取一个数字的二进制表示,反转它,然后再次得到一个数字。这使得这段代码非常可读,这应该是一个优先事项。

回答by Andrew Mao

There is an entire half chapter of Hacker's Delightdevoted to this issue (Section 7-1: Reversing Bits and Bytes) using binary operations, bit shifts, and other goodies. Seems like these are all possible in Pythonand it should be much quicker than the binary-to-string-and-reverse methods.

Hacker's Delight有整整半章专门讨论这个问题(第 7-1 节:反转位和字节)使用二进制运算、位移和其他优点。似乎这些在 Python 中都是可能的,它应该比二进制到字符串和反向方法快得多。

The book isn't available publicly but I found this blog post that discusses some of it. The method shown in the blog post follows the following quote from the book:

这本书不公开,但我发现这篇博客文章讨论了其中的一些内容。博客文章中显示的方法遵循书中的以下引用:

Bit reversal can be done quite efficiently by interchanging adjacent single bits, then interchanging adjacent 2-bit fields, and so on, as shown below. These five assignment statements can be executed in any order.

通过交换相邻的单个位,然后交换相邻的 2 位字段等,可以非常有效地完成位反转,如下所示。这五个赋值语句可以按任意顺序执行。

http://blog.sacaluta.com/2011/02/hackers-delight-reversing-bits.html

http://blog.sacaluta.com/2011/02/hackers-delight-reversing-bits.html

回答by Kelsey

You could do it with shift operators like this:

你可以用这样的移位运算符来做到这一点:

def revbits(x):
    rev = 0
    while x:
        rev <<= 1
        rev += x & 1
        x >>= 1
    return rev

It doesn't seem any faster than your method, though (in fact, slightly slower for me).

不过,它似乎并不比您的方法快(实际上,对我来说稍微慢一些)。

回答by Eugene Yarmash

>>> def bit_rev(n):
...     return int(bin(n)[:1:-1], 2)
...
>>> bit_rev(2)
1
>>>bit_rev(10)
5