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安全字符串?


当前回答

虽然目前排名第一的答案绝对是一个很棒的解决方案,但仍然有更多用户可能喜欢的定制。

Basencode添加了其中的一些特性,包括浮点数的转换、修改数字(在链接的答案中,只能使用数字)。

下面是一个可能的用例:

>>> from basencode import *
>>> n1 = Number(12345)
>> n1.repr_in_base(64) # convert to base 64
'30V'
>>> Number('30V', 64) # construct Integer from base 64
Integer(12345)
>>> n1.repr_in_base(8)
'30071'
>>> n1.repr_in_octal() # shortcuts
'30071'
>>> n1.repr_in_bin() # equivelant to `n1.repr_in_base(2)`
'11000000111001'
>>> n1.repr_in_base(2, digits=list('-+')) # override default digits: use `-` and `+` in place of `0` and `1`
'++------+++--+'
>>> n1.repr_in_base(33) # yet another base - all bases from 2 to 64 are supported from the start
'bb3'

你怎么添加你想要的碱基?让我复制一下目前投票最多的答案的例子:digits参数允许您覆盖从2到64的默认数字,并为任何高于该基数的数字提供数字。mode参数决定了表示的值如何决定(列表或字符串)如何返回答案。

>>> n2 = Number(67854 ** 15 - 102)
>>> n2.repr_in_base(577, digits=[str(i) for i in range(577)], mode="l")
['4', '473', '131', '96', '431', '285', '524', '486', '28', '23', '16', '82', '292', '538', '149', '25', '41', '483', '100', '517', '131', '28', '0', '435', '197', '264', '455']
>>> n2.repr_in_base(577, mode="l") # the program remembers the digits for base 577 now
['4', '473', '131', '96', '431', '285', '524', '486', '28', '23', '16', '82', '292', '538', '149', '25', '41', '483', '100', '517', '131', '28', '0', '435', '197', '264', '455']

可以执行以下操作:Number类返回basencode的一个实例。如果提供的数字是Integer,则返回一个基本编码。浮动

>>> n3 = Number(54321) # the Number class returns an instance of `basencode.Integer` if the provided number is an Integer, otherwise it returns a `basencode.Float`.
>>> n1 + n3
Integer(66666)
>>> n3 - n1
Integer(41976)
>>> n1 * n3
Integer(670592745)
>>> n3 // n1
Integer(4)
>>> n3 / n1 # a basencode.Float class allows conversion of floating point numbers
Float(4.400243013365735)
>>> (n3 / n1).repr_in_base(32)
'4.cpr56v6rnc4oitoblha2r11sus0dheqd4pgechfcjklo74b2bgom7j8ih86mipdvss0068sehi9f3791mdo4uotfujq66cf0jkgo'
>>> n4 = Number(0.5) # returns a basencode.Float
>>> n4.repr_in_bin() # binary version of 0.5
'0.1'

免责声明:此项目正在积极维护中,我是贡献者。

其他回答

这就是我的方法。首先转换数字,然后将其转换为字符串。

    def to_base(n, base):
        if base == 10:
            return n
        
        result = 0
        counter = 0
        
        while n:
            r = n % base
            n //= base
            result += r * 10**counter
            counter+=1
        return str(result)
def base_conversion(num, base):
    digits = []
    while num > 0:
        num, remainder = divmod(num, base)
        digits.append(remainder)
    return digits[::-1]
def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])

裁判: http://code.activestate.com/recipes/65212/

请注意这可能会导致

RuntimeError: maximum recursion depth exceeded in cmp

对于非常大的整数。

一个递归的解决方案。当然,这对负二进制值不起作用。您需要实现Two's Complement。

def generateBase36Alphabet():
    return ''.join([str(i) for i in range(10)]+[chr(i+65) for i in range(26)])

def generateAlphabet(base):
    return generateBase36Alphabet()[:base]

def intToStr(n, base, alphabet):
    def toStr(n, base, alphabet):
        return alphabet[n] if n < base else toStr(n//base,base,alphabet) + alphabet[n%base]
    return ('-' if n < 0 else '') + toStr(abs(n), base, alphabet)

print('{} -> {}'.format(-31, intToStr(-31, 16, generateAlphabet(16)))) # -31 -> -1F

递归

我将投票最多的答案简化为:

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(n, b): 
    return "0" if not n else to_base(n//b, b).lstrip("0") + BS[n%b]

对于RuntimeError有相同的建议:对于非常大的整数和负数,在cmp中超过最大递归深度。(你可以使用setrecursionlimit(new_limit))

迭代

为了避免递归问题:

BS="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
def to_base(s, b):
    res = ""
    while s:
        res+=BS[s%b]
        s//= b
    return res[::-1] or "0"