Python允许从给定基数的字符串中轻松创建一个整数

int(str, base). 

我想执行相反的操作:从一个整数创建一个字符串, 例如,我想要一些函数int2base(num, base),这样:

int(int2base(x, b), b) == x

函数名/参数的顺序并不重要。

对于int()将接受的任何以b为底的数字x。

这是一个很容易写的函数:事实上,它比在这个问题中描述它更容易。然而,我觉得我一定是错过了什么。

我知道函数bin, oct, hex,但我不能使用它们的几个原因:

这些函数在旧版本的Python中不可用,我需要与(2.2)兼容 我想要一个通解对于不同的碱都可以用同样的方式表示 我想允许2 8 16以外的底数

相关的

Python优雅的int(string, base)逆函数 在python中使用递归的整数到base-x系统 Python中的Base 62转换 如何在Python中将整数转换为最短的url安全字符串?


当前回答

我知道这是一个老帖子,但我只是把我的解决方案留在这里以防万一。

def decimal_to_given_base(integer_to_convert, base):
     remainder = integer_to_convert // base
     digit = integer_to_convert % base
     if integer_to_convert == 0:
         return '0'
     elif remainder == 0:
         return str(digit)
     else:
         return decimal_to_given_base(remainder, base) + str(digit)

其他回答

下面是一个处理有符号整数和自定义数字的递归版本。

import string

def base_convert(x, base, digits=None):
    """Convert integer `x` from base 10 to base `base` using `digits` characters as digits.
    If `digits` is omitted, it will use decimal digits + lowercase letters + uppercase letters.
    """
    digits = digits or (string.digits + string.ascii_letters)
    assert 2 <= base <= len(digits), "Unsupported base: {}".format(base)
    if x == 0:
        return digits[0]
    sign = '-' if x < 0 else ''
    x = abs(x)
    first_digits = base_convert(x // base, base, digits).lstrip(digits[0])
    return sign + first_digits + digits[x % base]
"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144

另一个简短的(在我看来更容易理解):

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    return (int_to_str(n/b, b, symbols) if n >= b else "") + symbols[n%b]

通过适当的异常处理:

def int_to_str(n, b, symbols='0123456789abcdefghijklmnopqrstuvwxyz'):
    try:
        return (int_to_str(n/b, b) if n >= b else "") + symbols[n%b]
    except IndexError:
        raise ValueError(
            "The symbols provided are not enough to represent this number in "
            "this base")

我写了这个函数,我用它来编码不同的碱基。我还提供了通过值“offset”来移动结果的方法。如果你想编码到64进制以上,但保持可显示字符(如95进制),这是有用的。

我还试图避免反转输出“列表”,并尽量减少计算操作。pow(base)数组是根据需要计算的,并保留用于对函数的其他调用。

输出是一个二进制字符串

pows = {}

######################################################
def encode_base(value,
                base = 10,
                offset = 0) :

    """
    Encode value into a binary string, according to the desired base.

    Input :
        value : Any positive integer value
        offset : Shift the encoding (eg : Starting at chr(32))
        base : The base in which we'd like to encode the value

    Return : Binary string

    Example : with : offset = 32, base = 64

              100 -> !D
              200 -> #(
    """

    # Determine the number of loops
    try :
        pb = pows[base]

    except KeyError :
        pb = pows[base] = {n : base ** n for n in range(0, 8) if n < 2 ** 48 -1}

    for n in pb :
        if value < pb[n] :
            n -= 1
            break

    out = []
    while n + 1 :
        b = pb[n]
        out.append(chr(offset + value // b))
        n -= 1
        value %= b

    return ''.join(out).encode()
def int2base(a, base, numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    baseit = lambda a=a, b=base: (not a) and numerals[0]  or baseit(a-a%b,b*base)+numerals[a%b%(base-1) or (a%b) and (base-1)]
    return baseit()

解释

在任何底数下,每个数字都等于a1+a2*base**2+a3*base**3…“任务”是找出所有的a。

everyN = 1、2、3……代码通过b对b=base**(N+1)进行“模组”来隔离aN*base**N, b=base**(N+1)切片所有大于N的a,并通过每次由当前aN*base**N调用func时减少a来切片它们的序列小于N的所有a。

底%(底-1)==1,则底**p%(底-1)==1,而底q*底^p%(底-1)==q,只有当q=底-1时例外,返回0。 为了解决这个问题,如果它返回0,func会检查它从原点开始是否是0。


优势

在这个例子中,只有一个乘法(而不是除法)和一些模量运算,这些运算相对花费的时间较少。