Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/332.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长对象中1位的位置_Python_Binary_Bit Manipulation_Bitwise Operators - Fatal编程技术网

获取python长对象中1位的位置

获取python长对象中1位的位置,python,binary,bit-manipulation,bitwise-operators,Python,Binary,Bit Manipulation,Bitwise Operators,假设我有一个非常大的python整数,在Python2.7中(尽管如果需要,我不介意切换到Python3) 比2^100000更大的东西 我能找到二进制序列中所有1的位置的最快方法是什么?(例如:24将是11000--->=[4,5](或[5,4]…我不关心订单) 目前我正在使用: sum = whatever_starting_number while 1: val = sum.bit_length()-1 sum -= 2**val mylist.append(va

假设我有一个非常大的python整数,在Python2.7中(尽管如果需要,我不介意切换到Python3)

比2^100000更大的东西

我能找到二进制序列中所有1的位置的最快方法是什么?(例如:24将是11000--->=[4,5](或[5,4]…我不关心订单)

目前我正在使用:

sum = whatever_starting_number

while 1:
    val = sum.bit_length()-1
    sum -= 2**val
    mylist.append(val)
    if sum == 0:
        break
这没关系,但它几乎比只取log2并重复减去它还要快。我真正想做的是只看位,跳过零,记录1s的位置,甚至不需要修改原始值


编辑:获得多个答案,非常感谢。我将在几次timeit测试中实现它们,明天将更新结果。

您可以使用位运算符

one_bit_indexes = []
index = 0
while sum: # returns true if sum is non-zero
    if sum & 1: # returns true if right-most bit is 1
        one_bit_indexes.append(index)
    sum >>= 1 # discard the right-most bit
    index += 1
我还没有测试过这一点,但很确定它会起作用。按位运算速度很快,因此这应该比计算和减去2的幂更有效。(除非你的Python解释器已经在做一些聪明的事情,比如转换代码,用按位运算替换2的幂)


编辑:要使其适用于负数,您必须首先获取“sum”的绝对值。

也许这足够快:

mylist = [i for i in range(sum.bit_length()) if sum & (1<<i)]

mylist=[i for i in range(sum.bit_length())if sum&(1可能不是最快的解决方案,但相当简单,似乎足够快(2^1M是即时的)

为了防止
[:1:-1]
不清楚,它被称为“扩展切片”,更多信息如下:

编辑:由于我不太同意@Voo对本案的评论和否决票,我决定对答案中公布的3个解决方案计时,结果如下:

import timeit


def fcn1():
    sum = 3**100000
    one_bit_indexes = []
    index = 0
    while sum: # returns true if sum is non-zero
        if sum & 1: # returns true if right-most bit is 1
            one_bit_indexes.append(index)
        sum >>= 1 # discard the right-most bit
        index += 1
    return one_bit_indexes


def fcn2():
    number = 3**100000
    bits = []
    for i, c in enumerate(bin(number)[:1:-1], 1):
        if c == '1':
            bits.append(i)
    return bits


def fcn3():
    sum = 3**100000
    return [i for i in range(sum.bit_length()) if sum & (1<<i)]


print(timeit.timeit(fcn1, number=1))
print(timeit.timeit(fcn2, number=1))
print(timeit.timeit(fcn3, number=1))
import timeit
def fcn1():
总和=3**100000
一位索引=[]
索引=0
while sum:#如果sum非零,则返回true
if sum&1:#如果最右边的位为1,则返回true
一位索引。追加(索引)
总和>>=1#丢弃最右边的位
指数+=1
返回一位索引
def fcn2():
数量=3**100000
位=[]
对于枚举中的i,c(bin(number)[:1:-1],1]:
如果c=='1':
位附加(i)
返回位
def fcn3():
总和=3**100000

返回[i for i in range(sum.bit_length()),如果sum&(1i如果调用
enumerate()
您可以取消计数器:
对于i,c in enumerate(str(bin(24))[:1:-1],1:
bin
已经生成字符串时,调用
str
没有意义。通常,如果使用字符串操作处理数字,您可以替换“可能不是最快的解决方案”和“保证在内存和性能方面都是最低效的解决方案”。很难说,但我的猜测是,其他两种解决方案都需要在不同内存之间重复移动/创建大量数字(我认为sum>>=1将创建一个新数字),而此解决方案保持大数不变,不创建任何新的大数,只处理小数(索引)。但实际上这只是猜测。|不管怎样,现在发现:|在纯Python中似乎做得再好不过了。在C中,情况会有所不同。你是对的。字符串解决方案的性能在Python中确实是最好的,即使在使用
to_bytes
和co时也是如此。似乎cpython没有利用inplace操作符一次又一次地分配相同的数字,这对性能有很大的影响。向上投票。哦,非常好。这基本上是我自己想出来的,但使用&with 1是我缺少的聪明部分。你不应该使用变量名
sum
,因为它是Python中内置函数的名称
import timeit


def fcn1():
    sum = 3**100000
    one_bit_indexes = []
    index = 0
    while sum: # returns true if sum is non-zero
        if sum & 1: # returns true if right-most bit is 1
            one_bit_indexes.append(index)
        sum >>= 1 # discard the right-most bit
        index += 1
    return one_bit_indexes


def fcn2():
    number = 3**100000
    bits = []
    for i, c in enumerate(bin(number)[:1:-1], 1):
        if c == '1':
            bits.append(i)
    return bits


def fcn3():
    sum = 3**100000
    return [i for i in range(sum.bit_length()) if sum & (1<<i)]


print(timeit.timeit(fcn1, number=1))
print(timeit.timeit(fcn2, number=1))
print(timeit.timeit(fcn3, number=1))