python-3.x 如何将一个数分解为2的幂?

ulmd4ohb  于 2023-05-19  发布在  Python
关注(0)|答案(9)|浏览(142)

我试图创建一个函数,它接收一个数字作为参数,并对该数字执行操作,以找出它最接近的2的幂,然后将其加起来。例如,如果用户输入4,则函数将追加4,因为它已经是2的幂。如果用户输入14,则函数应看到14不是2的幂,并且构成14的最接近的2的幂是2、4和8。
关键提示:我只会上升到2^9。
到目前为止我所拥有的:

def powers_finder(n):
    powers=[]
    i=0
    total=0
    while i<10:
         value=2**i
         total=total+value
         i=i+1
         #This if statement is for if the user enters a power of 2 as n
         #Then the number will be appended right away into my powers list.
         if value==n:
            powers.append(value)

这里的问题是,如果用户输入5,假设(n)5由幂2^2=4和2^0=1 4+1=5组成。如何扩展我的功能以包含此过程?
谢谢!

ryevplcw

ryevplcw1#

下面的二进制解决方案结合了@moose对enumerate()的使用、@ gbriones.gdl对stride索引的使用以及@gbriones.gdl关于一行的评论(实际上,这是一个关于 * 不是 * 一行的评论,但是一行很有趣)。

def powers(n):
    return [2**p for p,v in enumerate(bin(n)[:1:-1]) if int(v)]
41zrol4v

41zrol4v2#

当然,最好和最快的方法是使用二进制数,但这里有一种使用生成器的方法:

def powers_finder(num):
    d = []
    while sum(d) < num:
        p = powers_of_2()
        a=b=1
        while sum(d)+a<=num:
            b=a
            a = next(p)
        d.append(b)
    d.reverse()
    return d

def powers_of_2():
    n=1
    while 1:
        yield n
        n*=2
>>> print(powers_finder(5))
[1, 4]
>>> print(powers_finder(8))
[8]
>>> print(powers_finder(9))
[1, 8]
>>> print(powers_finder(14))
[2, 4, 8]
b5buobof

b5buobof3#

一个简单(但实际上并不有效)的方法是使用回溯。请注意,2的最接近的幂很容易通过使用math.log函数找到(n的2的最接近的幂是2^round(log(n, 2))):

from math import log

def powers_finder(n):
    return powers_finder_rec(n, [2**x for x in range(round(log(n, 2)+1))])

def powers_finder_rec(n, powers):
    if sum(powers) == n:
        return powers

    for i, j in enumerate(powers):
        (res1, res2) = (powers_finder_rec(n-j, powers[:i] + powers[i+1:]),  
                                    powers_finder_rec(n, powers[:i] + powers[i+1:]))
        if res1 or res2:
            return [j] + res1 if res1 else res2

    return []

print(powers_finder(13))
print(powers_finder(112))

输出:

[1, 4, 8]
[16, 32, 64]
xqk2d5yq

xqk2d5yq4#

这个想法是将数字转换为二进制,然后从二进制表示中获得2的幂:

#!/usr/bin/env python

def get_powers(n):
    """Get positive powers of two which add up to n.

    Parameters
    ----------
    n : positive integer

    Returns
    -------
    list of integers which are powers of 2

    Examples
    --------
    >>> get_powers(14)
    [2, 4, 8]

    >>> get_powers(5)
    [1, 4]
    """
    get_bin = lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
    bin_str = get_bin(n)  # convert n to a binary string
    powers = []
    for i, digit in enumerate(bin_str[::-1]):
        if digit == '1':
            powers.append(2**i)
    return powers
czq61nw1

czq61nw15#

我知道这是旧的,但我相信我已经找到了一个更快的解决方案。
我的代码:

from collections import deque

def decompose(n):
    powers = deque()
    for p in range(n.bit_length(), -1, -1):
        power = 1 << p
        if n & power:
            powers.append(power)
    return powers

deque.appendlist.append更高效,我在Python中观察到,for循环似乎比while循环更快,int有一个方法bit_length,根据定义,它是大于或等于该数字的最接近的2的幂。
我测试了我的代码,发现它和公认的答案一样快(或比):

In [69]: def powers_of_2(x):
    ...:     powers = []
    ...:     i = 1
    ...:     while i <= x:
    ...:         if i & x:
    ...:             powers.append(i)
    ...:         i <<= 1
    ...:     return powers
    ...:
    ...: def decompose(n):
    ...:     powers = deque()
    ...:     for p in range(n.bit_length(), -1, -1):
    ...:         power = 1 << p
    ...:         if n & power:
    ...:             powers.append(power)
    ...:     return powers

In [70]: %timeit powers_of_2(123456789)
4.2 µs ± 82.6 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [71]: %timeit decompose(123456789)
4.06 µs ± 40.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [72]: %timeit powers_of_2(123456789)
4.04 µs ± 38.7 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [73]: %timeit decompose(123456789)
4.07 µs ± 66.4 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [74]: %timeit powers_of_2(123456789)
4.07 µs ± 86.6 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [75]: %timeit decompose(123456789)
4.02 µs ± 70.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

我的代码反汇编:

In [76]: import dis

In [77]: dis.dis(decompose)
 11           0 LOAD_GLOBAL              0 (deque)
              2 CALL_FUNCTION            0
              4 STORE_FAST               1 (powers)

 12           6 LOAD_GLOBAL              1 (range)
              8 LOAD_FAST                0 (n)
             10 LOAD_METHOD              2 (bit_length)
             12 CALL_METHOD              0
             14 LOAD_CONST               1 (-1)
             16 LOAD_CONST               1 (-1)
             18 CALL_FUNCTION            3
             20 GET_ITER
        >>   22 FOR_ITER                15 (to 54)
             24 STORE_FAST               2 (p)

 13          26 LOAD_CONST               2 (1)
             28 LOAD_FAST                2 (p)
             30 BINARY_LSHIFT
             32 STORE_FAST               3 (power)

 14          34 LOAD_FAST                0 (n)
             36 LOAD_FAST                3 (power)
             38 BINARY_AND
             40 POP_JUMP_IF_FALSE       26 (to 52)

 15          42 LOAD_FAST                1 (powers)
             44 LOAD_METHOD              3 (append)
             46 LOAD_FAST                3 (power)
             48 CALL_METHOD              1
             50 POP_TOP
        >>   52 JUMP_ABSOLUTE           11 (to 22)

 16     >>   54 LOAD_FAST                1 (powers)
             56 RETURN_VALUE

事实上,我找到了另一个绝对最快的解决方案:

In [78]: def string_decompose(n):
    ...:     return [1 << i for i, b in enumerate(bin(n).removeprefix('0b')[::-1]) if b == '1']

In [79]: %timeit string_decompose(123456789)
3.33 µs ± 109 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [80]: %timeit string_decompose(123456789)
3.3 µs ± 99.3 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [81]: %timeit string_decompose(123456789)
3.29 µs ± 143 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [82]: %timeit string_decompose(123456789)
3.34 µs ± 130 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [83]: %timeit string_decompose(123456789)
3.21 µs ± 91 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [84]: dis.dis(string_decompose)
  2           0 LOAD_CONST               1 (<code object <listcomp> at 0x000001B8E632EFA0, file "<ipython-input-78-850487af6434>", line 2>)
              2 LOAD_CONST               2 ('string_decompose.<locals>.<listcomp>')
              4 MAKE_FUNCTION            0
              6 LOAD_GLOBAL              0 (enumerate)
              8 LOAD_GLOBAL              1 (bin)
             10 LOAD_FAST                0 (n)
             12 CALL_FUNCTION            1
             14 LOAD_METHOD              2 (removeprefix)
             16 LOAD_CONST               3 ('0b')
             18 CALL_METHOD              1
             20 LOAD_CONST               0 (None)
             22 LOAD_CONST               0 (None)
             24 LOAD_CONST               4 (-1)
             26 BUILD_SLICE              3
             28 BINARY_SUBSCR
             30 CALL_FUNCTION            1
             32 GET_ITER
             34 CALL_FUNCTION            1
             36 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x000001B8E632EFA0, file "<ipython-input-78-850487af6434>", line 2>:
  2           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                12 (to 30)
              6 UNPACK_SEQUENCE          2
              8 STORE_FAST               1 (i)
             10 STORE_FAST               2 (b)
             12 LOAD_FAST                2 (b)
             14 LOAD_CONST               0 ('1')
             16 COMPARE_OP               2 (==)
             18 POP_JUMP_IF_FALSE        2 (to 4)
             20 LOAD_CONST               1 (1)
             22 LOAD_FAST                1 (i)
             24 BINARY_LSHIFT
             26 LIST_APPEND              2
             28 JUMP_ABSOLUTE            2 (to 4)
        >>   30 RETURN_VALUE

不知何故,如果我处理字符串的顺序,它变得更慢:

In [85]: def string_decompose(n):
    ...:     l = n.bit_length()
    ...:     return [1 << (l - i) for i, b in enumerate(bin(n).removeprefix('0b')) if b == '1']

In [86]: %timeit string_decompose(123456789)
3.57 µs ± 62 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [87]: %timeit string_decompose(123456789)
3.63 µs ± 56.5 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [88]: %timeit string_decompose(123456789)
3.65 µs ± 89.3 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [89]: %timeit string_decompose(123456789)
3.62 µs ± 119 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [90]: dis.dis(string_decompose)
  2           0 LOAD_FAST                0 (n)
              2 LOAD_METHOD              0 (bit_length)
              4 CALL_METHOD              0
              6 STORE_DEREF              0 (l)

  3           8 LOAD_CLOSURE             0 (l)
             10 BUILD_TUPLE              1
             12 LOAD_CONST               1 (<code object <listcomp> at 0x000001B8EE45A1E0, file "<ipython-input-85-9aa9914d35b1>", line 3>)
             14 LOAD_CONST               2 ('string_decompose.<locals>.<listcomp>')
             16 MAKE_FUNCTION            8 (closure)
             18 LOAD_GLOBAL              1 (enumerate)
             20 LOAD_GLOBAL              2 (bin)
             22 LOAD_FAST                0 (n)
             24 CALL_FUNCTION            1
             26 LOAD_METHOD              3 (removeprefix)
             28 LOAD_CONST               3 ('0b')
             30 CALL_METHOD              1
             32 CALL_FUNCTION            1
             34 GET_ITER
             36 CALL_FUNCTION            1
             38 RETURN_VALUE

Disassembly of <code object <listcomp> at 0x000001B8EE45A1E0, file "<ipython-input-85-9aa9914d35b1>", line 3>:
  3           0 BUILD_LIST               0
              2 LOAD_FAST                0 (.0)
        >>    4 FOR_ITER                14 (to 34)
              6 UNPACK_SEQUENCE          2
              8 STORE_FAST               1 (i)
             10 STORE_FAST               2 (b)
             12 LOAD_FAST                2 (b)
             14 LOAD_CONST               0 ('1')
             16 COMPARE_OP               2 (==)
             18 POP_JUMP_IF_FALSE        2 (to 4)
             20 LOAD_CONST               1 (1)
             22 LOAD_DEREF               0 (l)
             24 LOAD_FAST                1 (i)
             26 BINARY_SUBTRACT
             28 BINARY_LSHIFT
             30 LIST_APPEND              2
             32 JUMP_ABSOLUTE            2 (to 4)
        >>   34 RETURN_VALUE

不知何故,在整数域中操作比从二进制中提取幂要慢:

def listcomp_decompose(n):
    return [power for p in range(n.bit_length(), -1, -1) if (power := 1 << p) & n]
In [91]: def listcomp_decompose(n):
    ...:     return [power for p in range(n.bit_length(), -1, -1) if (power := 1 << p) & n]

In [92]: %timeit listcomp_decompose(123456789)
3.85 µs ± 87.1 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [93]: %timeit listcomp_decompose(123456789)
4.18 µs ± 804 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [94]: %timeit listcomp_decompose(123456789)
3.82 µs ± 99.8 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)

In [95]: %timeit listcomp_decompose(123456789)
3.78 µs ± 79.8 ns per loop (mean ± std. dev. of 7 runs, 100,000 loops each)
8tntrjer

8tntrjer6#

与其解决问题,不如提供一些信息来帮助你解决问题?看几个例子,并解决它们。这里有几个,
假设N=2,那么答案是= {2=2^1}。
假设N=3,那么答案是= {2= 2^1,1 =2^0}(注意2**0=1)
假设N=4,则答案为= {4=2^2}
...
假设N=63,则答案= {32=2^5,16=2^4,8=2^3,4=2^2,2=2^1,1=2^0}
假设N=64,则答案为= {64=2^6}
...
假设N=259,则答案为= {256=2^8,2=2^1,1=2^0}
你看出规律了吗?
想要算法吗?
想想这些简单的步骤,然后把它们组合在一起,
你能查一下这个号码是不是奇数吗?当数字是奇数时,则您检测到一个“on”位。减一(使数字为偶数)。
你能除以2吗?你对结果做了什么?

js5cn81o

js5cn81o7#

最有效的方法是:

def myfunc(x):
    powers = []
    i = 1
    while i <= x:
        if i & x:
            powers.append(i)
        i <<= 1
    return powers
pbgvytdp

pbgvytdp8#

我们现在对这个问题有了一些很好的答案。我想我应该用distimeit来分析一下它们。
下面是我使用的测试代码:

import dis
import timeit

def gbriones_gdl(num):
    result = []
    binary = bin(num)[:1:-1]
    for x in range(len(binary)):
        if int(binary[x]):
            result.append(2**x)
    return result

def nullptr(num):
    powers = []
    i = 1
    while i <= num:
        if i & num:
            powers.append(i)
        i <<= 1
    return powers

def t3_gen(num):
    d = []
    while sum(d) < num:
        p = powers_of_2()
        a=b=1
        while sum(d)+a<=num:
            b=a
            a = next(p)
        d.append(b)
    d.reverse()
    return d

def powers_of_2():
    n=1
    while 1:
        yield n
        n*=2

def t3_enum(num):
    return [2**p for p,v in enumerate(bin(num)[:1:-1]) if int(v)]

def moose(num):
    get_bin = lambda x: x >= 0 and str(bin(x))[2:] or "-" + str(bin(x))[3:]
    bin_str = get_bin(num)  # convert num to a binary string
    powers = []
    for i, digit in enumerate(bin_str[::-1]):
        if digit == '1':
            powers.append(2**i)
    return powers

print('Each function gives correct results:', nullptr(1048575) == moose(1048575) ==
t3_enum(1048575) == gbriones_gdl(1048575) ==
t3_gen(1048575))
print()

print('nullptr'.ljust(15), timeit.timeit('nullptr(1048575)', 'from __main__ import nullptr', number=100000))
print('moose'.ljust(15), timeit.timeit('moose(1048575)', 'from __main__ import moose', number=100000))
print('t3_enum'.ljust(15), timeit.timeit('t3_enum(1048575)', 'from __main__ import t3_enum', number=100000))
print('gbriones_gdl'.ljust(15), timeit.timeit('gbriones_gdl(1048575)', 'from __main__ import gbriones_gdl', number=100000))
print('t3_gen'.ljust(15), timeit.timeit('t3_gen(1048575)', 'from __main__ import t3_gen', number=100000))
print('\nnullptr:\n===========================')
print(dis.dis(nullptr))
print('\nmoose:\n===========================')
print(dis.dis(moose))
print('\nt3_enum:\n===========================')
print(dis.dis(t3_gen))
print('gbriones_gdl:\n===========================')
print(dis.dis(t3_enum))
print('\nt3_gen:\n===========================')
print(dis.dis(gbriones_gdl))

结果如下:

Each function gives correct results: True

nullptr         0.7847449885390462
moose           1.810839785503465
t3_enum         2.898256901365956
gbriones_gdl    3.0904670146624778
t3_gen          21.366890624367063

nullptr:
===========================
 14           0 BUILD_LIST               0
              3 STORE_FAST               1 (powers)

 15           6 LOAD_CONST               1 (1)
              9 STORE_FAST               2 (i)

 16          12 SETUP_LOOP              52 (to 67)
        >>   15 LOAD_FAST                2 (i)
             18 LOAD_FAST                0 (num)
             21 COMPARE_OP               1 (<=)
             24 POP_JUMP_IF_FALSE       66

 17          27 LOAD_FAST                2 (i)
             30 LOAD_FAST                0 (num)
             33 BINARY_AND
             34 POP_JUMP_IF_FALSE       53

 18          37 LOAD_FAST                1 (powers)
             40 LOAD_ATTR                0 (append)
             43 LOAD_FAST                2 (i)
             46 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             49 POP_TOP
             50 JUMP_FORWARD             0 (to 53)

 19     >>   53 LOAD_FAST                2 (i)
             56 LOAD_CONST               1 (1)
             59 INPLACE_LSHIFT
             60 STORE_FAST               2 (i)
             63 JUMP_ABSOLUTE           15
        >>   66 POP_BLOCK

 20     >>   67 LOAD_FAST                1 (powers)
             70 RETURN_VALUE
None

moose:
===========================
 44           0 LOAD_CONST               1 (<code object <lambda> at 0x0000000002A8E660, file "power_2_adder.py", line 44>)
              3 LOAD_CONST               2 ('moose.<locals>.<lambda>')
              6 MAKE_FUNCTION            0
              9 STORE_FAST               1 (get_bin)

 45          12 LOAD_FAST                1 (get_bin)
             15 LOAD_FAST                0 (num)
             18 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             21 STORE_FAST               2 (bin_str)

 46          24 BUILD_LIST               0
             27 STORE_FAST               3 (powers)

 47          30 SETUP_LOOP              71 (to 104)
             33 LOAD_GLOBAL              0 (enumerate)
             36 LOAD_FAST                2 (bin_str)
             39 LOAD_CONST               0 (None)
             42 LOAD_CONST               0 (None)
             45 LOAD_CONST               6 (-1)
             48 BUILD_SLICE              3
             51 BINARY_SUBSCR
             52 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             55 GET_ITER
        >>   56 FOR_ITER                44 (to 103)
             59 UNPACK_SEQUENCE          2
             62 STORE_FAST               4 (i)
             65 STORE_FAST               5 (digit)

 48          68 LOAD_FAST                5 (digit)
             71 LOAD_CONST               4 ('1')
             74 COMPARE_OP               2 (==)
             77 POP_JUMP_IF_FALSE       56

 49          80 LOAD_FAST                3 (powers)
             83 LOAD_ATTR                1 (append)
             86 LOAD_CONST               5 (2)
             89 LOAD_FAST                4 (i)
             92 BINARY_POWER
             93 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             96 POP_TOP
             97 JUMP_ABSOLUTE           56
            100 JUMP_ABSOLUTE           56
        >>  103 POP_BLOCK

 50     >>  104 LOAD_FAST                3 (powers)
            107 RETURN_VALUE
None

t3_enum:
===========================
 23           0 BUILD_LIST               0
              3 STORE_FAST               1 (d)

 24           6 SETUP_LOOP             101 (to 110)
        >>    9 LOAD_GLOBAL              0 (sum)
             12 LOAD_FAST                1 (d)
             15 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             18 LOAD_FAST                0 (num)
             21 COMPARE_OP               0 (<)
             24 POP_JUMP_IF_FALSE      109

 25          27 LOAD_GLOBAL              1 (powers_of_2)
             30 CALL_FUNCTION            0 (0 positional, 0 keyword pair)
             33 STORE_FAST               2 (p)

 26          36 LOAD_CONST               1 (1)
             39 DUP_TOP
             40 STORE_FAST               3 (a)
             43 STORE_FAST               4 (b)

 27          46 SETUP_LOOP              44 (to 93)
        >>   49 LOAD_GLOBAL              0 (sum)
             52 LOAD_FAST                1 (d)
             55 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             58 LOAD_FAST                3 (a)
             61 BINARY_ADD
             62 LOAD_FAST                0 (num)
             65 COMPARE_OP               1 (<=)
             68 POP_JUMP_IF_FALSE       92

 28          71 LOAD_FAST                3 (a)
             74 STORE_FAST               4 (b)

 29          77 LOAD_GLOBAL              2 (next)
             80 LOAD_FAST                2 (p)
             83 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             86 STORE_FAST               3 (a)
             89 JUMP_ABSOLUTE           49
        >>   92 POP_BLOCK

 30     >>   93 LOAD_FAST                1 (d)
             96 LOAD_ATTR                3 (append)
             99 LOAD_FAST                4 (b)
            102 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
            105 POP_TOP
            106 JUMP_ABSOLUTE            9
        >>  109 POP_BLOCK

 31     >>  110 LOAD_FAST                1 (d)
            113 LOAD_ATTR                4 (reverse)
            116 CALL_FUNCTION            0 (0 positional, 0 keyword pair)
            119 POP_TOP

 32         120 LOAD_FAST                1 (d)
            123 RETURN_VALUE
None
gbriones_gdl:
===========================
 41           0 LOAD_CONST               1 (<code object <listcomp> at 0x0000000002A8E540, file "power_2_adder.py", line 41>)
              3 LOAD_CONST               2 ('t3_enum.<locals>.<listcomp>')
              6 MAKE_FUNCTION            0
              9 LOAD_GLOBAL              0 (enumerate)
             12 LOAD_GLOBAL              1 (bin)
             15 LOAD_FAST                0 (num)
             18 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             21 LOAD_CONST               0 (None)
             24 LOAD_CONST               3 (1)
             27 LOAD_CONST               4 (-1)
             30 BUILD_SLICE              3
             33 BINARY_SUBSCR
             34 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             37 GET_ITER
             38 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             41 RETURN_VALUE
None

t3_gen:
===========================
  6           0 BUILD_LIST               0
              3 STORE_FAST               1 (result)

  7           6 LOAD_GLOBAL              0 (bin)
              9 LOAD_FAST                0 (num)
             12 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             15 LOAD_CONST               0 (None)
             18 LOAD_CONST               1 (1)
             21 LOAD_CONST               3 (-1)
             24 BUILD_SLICE              3
             27 BINARY_SUBSCR
             28 STORE_FAST               2 (binary)

  8          31 SETUP_LOOP              62 (to 96)
             34 LOAD_GLOBAL              1 (range)
             37 LOAD_GLOBAL              2 (len)
             40 LOAD_FAST                2 (binary)
             43 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             46 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             49 GET_ITER
        >>   50 FOR_ITER                42 (to 95)
             53 STORE_FAST               3 (x)

  9          56 LOAD_GLOBAL              3 (int)
             59 LOAD_FAST                2 (binary)
             62 LOAD_FAST                3 (x)
             65 BINARY_SUBSCR
             66 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             69 POP_JUMP_IF_FALSE       50

 10          72 LOAD_FAST                1 (result)
             75 LOAD_ATTR                4 (append)
             78 LOAD_CONST               2 (2)
             81 LOAD_FAST                3 (x)
             84 BINARY_POWER
             85 CALL_FUNCTION            1 (1 positional, 0 keyword pair)
             88 POP_TOP
             89 JUMP_ABSOLUTE           50
             92 JUMP_ABSOLUTE           50
        >>   95 POP_BLOCK

 11     >>   96 LOAD_FAST                1 (result)
             99 RETURN_VALUE
None

timeit的结果中,我们可以看到@nullptr的解决方案非常好,正如我所怀疑的那样,其次是@moose的解决方案。之后是我的@moose和@gbriones.gdl的解决方案的组合,紧接着是@gbriones.gdl的解决方案。我的发电机解决方案,可以说,非常次优,但我有点预料到了。
dis结果包括在内,以确保完整性。

avkwfej4

avkwfej49#

试试二进制文件:

def power_find(n):
    result = []
    binary = bin(n)[:1:-1]
    for x in range(len(binary)):
        if int(binary[x]):
            result.append(2**x)
    return result

>>> power_find(11)
[1, 2, 8]

相关问题