将电话号码范围列表转换为前缀列表

时间:2012-04-15 20:08:20

标签: python phone-number

我有一个电话号码范围,例如:

3331234-3332345

我需要编写一个将其转换为前缀列表的函数:

3331234
...
3331239
333124
...
333129
33313
...
33319
33320
...
33322
333231
333232
333233
3332341
...
3332345

问题并不那么容易。我不需要在范围开始和结束之间获得数字列表。

5 个答案:

答案 0 :(得分:1)

我的工作代码。它也不是很快。优化欢迎。

def diap_to_prefix(a, b):
    lst = ['%0*d'%(max(len(str(a)), len(str(b))), x) for x in range(int(a), int(b)+1)]
    new_lst = []

    while len(lst) != len(new_lst):
        lst = new_lst or lst
        new_lst = []

        c = lst[0]
        tmp_lst = [c]

        for i in lst[1:]:
            if c[:-1] == i[:-1]:
                c = i
                tmp_lst.append(c)
            else:
                if len(tmp_lst) == 10:
                    new_lst.append(c[:-1])
                else:
                    new_lst.extend(tmp_lst)

                c = i
                tmp_lst = [c]

        if len(tmp_lst) == 10:
            new_lst.append(c[:-1])
        else:
            new_lst.extend(tmp_lst)

    return lst

答案 1 :(得分:1)

我新的更优化解决方案(py3.4)

def diap_to_prefix(a, b):
    def inner(aa, bb, p):
        if p == 1:
            if a <= aa <= b:
                yield aa
            return

        for d in range(aa, bb + 1, p):
            if a <= d and d + p - 1 <= b:
                yield d // p
            elif not (bb < a or aa > b):
                for i in range(10):
                    yield from inner(d + i * p // 10, d + (i + 1) * p // 10 - 1, p // 10)

    a, b = int(a), int(b)
    p = 10**(max(len(str(x)) for x in (a, b)) - 1)
    yield from inner(a // p * p, b // p * p + p - 1, p)

答案 2 :(得分:0)

您需要获取由“ - ”分隔的值的公共前缀,所以:

  • 使用.split获取这些内容并进行迭代,直至找到差异
  • 用零填充第一个值(得到最少的数字),直到得到phone_len个数字,并做最大值(用9个)
  • 然后,你有一个简单的数字范围
  • 迭代它们并将它们转换为字符串

这是:

phone_len = 7
R = "33312345-3332345".split("-")

prefix = ""
for i in range(len(R[0])):
    if R[0][i] == R[1][i]:
        prefix += R[0][i]
    else:
        break

m = int(R[0]+"0"*(phone_len-len(R[0])))
M = int(R[1]+"9"*(phone_len-len(R[0])))

phones = [str(n) for n in range(m, M+1)]

答案 3 :(得分:0)

这是处理此问题的一种方法草图。我用椭圆来标记你需要填写评论中解释的细节的地方。我写了一个函数来推导'maxpower'的初始值,其他一切都很简单,可以内联写。

firstnumber = 3331234
lastnumber = 3332345

current = firstnumber

while current <= lastnumber:

    # Find the largest power of 10 that exactly divides 'current'.
    # Call this value 'maxpower'.  'maxpower' is a candidate for the
    # size of the block of numbers that will be represented by the 
    # next output value.

    maxpower = ...     # 1, 10, 100, 1000, 10000, and so on

    # If a block of size 'maxpower' would take us past the 
    # 'lastnumber', we can't use that block size.  We must try a
    # smaller block.  Divide 'maxpower' by 10 until the block size 
    # becomes acceptable.

    while (current + maxpower) > ... :
        maxpower /= 10

    # Now 'maxpower' is the largest acceptable size for the next 
    # block, so the desired prefix is 'current' divided by 'maxpower'.
    # Emit that value, then add 'maxpower' to 'current' to get the new
    # 'current' value for the next iteration.

    print ...
    current += maxpower

答案 4 :(得分:0)

我的工作代码。它不是很快,但工作。优化欢迎。

def fill(root, prefix, value, parent, pkey):
    if len(prefix) > 1:
        if prefix[0] in root:
            fill(root[prefix[0]], prefix[1:], value, root, prefix[0])
            if pkey:
                if len(parent[pkey]) == 10:
                    parent[pkey] = value
        elif type(root) == type({}):
            root[prefix[0]] = {}
            fill(root[prefix[0]], prefix[1:], value, root, prefix[0])
            if pkey:
                if len(parent[pkey]) == 10:
                    parent[pkey] = value
    elif type(root) == type({}):
        root[prefix[0]] = value
        if pkey:
            if len(parent[pkey]) == 10:
                parent[pkey] = value
    return root

def compact(prefixes, current):
    if not type(prefixes) == type({}):
        return [current]
    else:
        rlist = []
        for k, v in prefixes.iteritems():
            rlist.extend(compact(v, current + k))
            continue
        return rlist

if __name__ == '__main__':
    plist = {}
    for x in range(4440000, 4490000):
        fill(plist, str(x), 'value', plist, None)
    #print plist
    print compact(plist, '')