识别唯一数字ID来源的Python方法

时间:2019-12-18 21:53:49

标签: python performance

我将拥有一个庞大的唯一数字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]

4 个答案:

答案 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]