我将拥有一个庞大的唯一数字ID数据集,其中每个ID等于值列表的子集之和。
在一种情况下,值都是10 ^ x,其中1 <= x <= 23。所以我有一个清单
list1 = []
for x in range(1,24):
list1.append(10**x)
其中将包含从10到1e + 23的值列表。我的唯一ID是通过以下方式创建的:
idlist = [1,5,9,11]
uniqueID = 0
for x in idlist:
uniqueID += list1[x-1]
此唯一ID为101000100010,即10 ^ 1 + 10 ^ 5 + 10 ^ 9 + 10 ^ 11。但是,我需要做的是相反的操作,这里我有ID并想要值列表(“ idlist”)。我当前的方法(如下)有效,但是我无法想象这是最有效的方法。我非常感谢有关如何提高效率的任何建议。
idlist = []
for x in reversed(range(1,24)):
if uniqueID >= 10**x:
uniqueID -= 10**x
tmp.append(x)
“ idlist”正确返回[1,5,9,11]
答案 0 :(得分:1)
以下方法应该起作用:
def id_list(unique_id):
reversed = str(unique_id)[::-1]
result = [
i
for i, num in enumerate(reversed)
if num == "1"
]
return result
示例:id_list(101000100010)
的结果是:
[1, 5, 9, 12]
此函数的作用就是将ID转换为字符串,将其反转,然后检查每个字符以查看其是否等于"1"
。如果是,该字符的索引将添加到列表中。然后返回列表。
答案 1 :(得分:1)
您可以使用log10
模块中的math
来完成此操作。取log10
的整数可以使您获得数字中最大的10的幂。减去该值并重复直到数字为0。这将为您提供构成该数字的10的幂的列表。
如果数字不能完全分解,我在这里提出一个例外。
from math import log10
def decompose_10(x):
powers = []
while x:
p = int(log10(x))
if p < 1:
raise ValueError(f'{x} cannot be decomposed into sums of powers of 10')
powers.insert(0, p)
x = x - 10**p
return powers
x = 101000100010
decompose_10(x)
# returns:
[1, 5, 9, 11]
decompose_10(x+3)
# raises:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-69-7c6a1e865b34> in <module>
----> 1 decompose_10(x+3)
<ipython-input-68-6310bad29158> in decompose_10(x)
4 p = int(log10(x))
5 if p < 1:
----> 6 raise ValueError(f'{x} cannot be decomposed into sums of powers of 10')
7 powers.insert(0, p)
8 x = x - 10**p
ValueError: 3 cannot be decomposed into sums of powers of 10
答案 2 :(得分:1)
您还可以考虑以下使用模运算符查找1的方法。就是说,为了获得纯性能,您可能希望将唯一的ID从10 ^ N更改为2 ^ N,因为计算机可以更快地进行基于2的求幂和除法:
ids, x = [], 0
while uniqueId:
n = unqiueId % 10
uniqueId //= 10
if n:
ids.append(x)
x += 1
答案 3 :(得分:1)
import re
a = 101000100010
idlist = [ x.start() for x in re.finditer('1', str(a)[::-1]) ]
print(idlist)
# Output: [1, 5, 9, 11]