繁体   English   中英

光滑的方式来反转Python中数字的(二进制)数字?

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

我正在寻找一个光滑的函数,它反转数字的二进制表示的数字。

如果f是这样的功能我会

int(reversed(s),2) == f(int(s,2))每当s是一个零的字符串和一个以1开头的字符串。

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

就简洁而言,这是好的,但这似乎是一种相当迂回的方式。

我想知道是否有一个更好的(也许更快)的方式与位运算符,什么不是。

您可以使用这样的移位运算符来执行此操作:

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

它看起来并不比你的方法快(事实上,对我来说稍慢)。

怎么样

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

要么

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

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

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

这是我的建议:

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

同样的方法,略有简化。

我认为你当前的方法非常好,但你可以丢失list()调用,因为str.join()将接受任何iterable:

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

除了最简单的函数之外,它还建议不要使用lambda ,它只使用一次,并通过内联使周围的代码更清晰。

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

Hacker's Delight的整整半章专门针对这个问题(第7-1节:反转位和字节)使用二进制运算,位移和其他好东西。 看起来这些在Python中都是可能的 ,它应该比二进制到字符串和反向方法快得多。

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

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

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

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

暂无
暂无

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

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