如何将任何基数中的整数转换为字符串?

Mar*_*ing 186 python base radix

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

int(str, base). 
Run Code Online (Sandbox Code Playgroud)

我想执行逆向:从整数创建一个字符串,即我想要一些函数int2base(num, base),这样:

int(int2base(x, b), b) == x
Run Code Online (Sandbox Code Playgroud)

函数名称/参数顺序并不重要.

对于任何数量x和底座bint()会接受的.

这是一个很容易编写的函数:实际上它比在这个问题中描述它更容易.但是,我觉得我必须遗漏一些东西.

我知道的功能bin,oct,hex,但我不能使用他们的几个原因:

  • 这些函数在旧版本的Python上不可用,我需要与它兼容(2.2)

  • 我想要一个通用的解决方案,可以用不同的基础调用相同的方法

  • 我想允许2,8,16以外的碱基

有关

Sal*_*ali 93

令人惊讶的是,人们只提供转换为小基数的解决方案(小于英文字母的长度).没有尝试提供从2到无穷大转换为任意碱基的解决方案.

所以这是一个超级简单的解决方案:

def numberToBase(n, b):
    if n == 0:
        return [0]
    digits = []
    while n:
        digits.append(int(n % b))
        n //= b
    return digits[::-1]
Run Code Online (Sandbox Code Playgroud)

所以,如果你需要将一些超大数字转换为基数577,

numberToBase(67854 ** 15 - 102, 577),会给你一个正确的解决方案: [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],

您可以稍后将其转换为您想要的任何基础

  • 对于Python 3,由于"真正的除法",你需要`n // = b`而不是`n/= b`.这是一件很容易错过的事情,所以我在这里提到它. (27认同)
  • 该方法的反函数是什么? (2认同)
  • @plugwash 1)在某些时候您会注意到有时没有内置库函数可以完成您想要的操作,因此您需要编写自己的库函数。如果您不同意,请发布您自己的解决方案,其中包含一个内置函数,该函数可以将基数 10 的数字转换为基数 577。 2) 这是由于缺乏理解某些基数中的数字的含义。3)我鼓励您思考一下为什么您的方法中的 base 仅适用于 n <= 36。一旦完成,就会很明显为什么我的函数返回一个列表并具有它所具有的签名。 (2认同)
  • 如果您有一个字符串,例如 0-9 加 AZ 加 541 个额外的 unicode 字符,那么您如何将该列表转换为单个字符表示形式?`s = "0123456789ABCDEF"` `n = [15,1,13]` `"".join([s[x] for x in n])` (2认同)

Ale*_*lli 91

如果你需要兼容古老版本的Python,你可以使用gmpy(它包含一个快速的,完全通用的int-to-string转换函数,并且可以为这些古老的版本构建 - 你可能需要尝试旧的版本,因为最近的那些尚未经过古老的Python和GMP版本的测试,只有一些近期的版本),或者,为了更低的速度但更方便,使用Python代码 - 例如,最简单:

import string
digs = string.digits + string.ascii_letters


def int2base(x, base):
    if x < 0:
        sign = -1
    elif x == 0:
        return digs[0]
    else:
        sign = 1

    x *= sign
    digits = []

    while x:
        digits.append(digs[int(x % base)])
        x = int(x / base)

    if sign < 0:
        digits.append('-')

    digits.reverse()

    return ''.join(digits)
Run Code Online (Sandbox Code Playgroud)

  • 就在(gmpy2)案例中,亚历克斯所说的func似乎是`gmpy2.digits(x,base)`. (7认同)
  • (或`string.digits + string.letters`) (4认同)
  • @ lordscales91你也可以使用`x // = base`在Python 2中的行为类似于`/ =`来删除小数.这个答案应该包含一个免责声明,它适用于Python 2. (4认同)
  • 我注意到有些情况需要基数> 36,所以挖掘应该是`digs = string.digits + string.lowercase + string.uppercase` (2认同)
  • 知道为什么在Python中默认不包含convert-base-N-to-string?(它是在Javascript中.)是的,我们都可以编写自己的实现,但我一直在这个网站和其他地方搜索,其中许多都有错误.最好在核心发行版中包含一个经过测试,信誉良好的版本. (2认同)

jel*_*ree 88

def baseN(num,b,numerals="0123456789abcdefghijklmnopqrstuvwxyz"):
    return ((num == 0) and numerals[0]) or (baseN(num // b, b, numerals).lstrip(numerals[0]) + numerals[num % b])
Run Code Online (Sandbox Code Playgroud)

参考:http: //code.activestate.com/recipes/65212/

请注意,这可能会导致

RuntimeError: maximum recursion depth exceeded in cmp
Run Code Online (Sandbox Code Playgroud)

对于非常大的整数.

  • 优雅简洁.对于非负整数,它似乎在python 2.2.3下工作.负数无限递归. (5认同)
  • 这默默地失败了(a)当base是>`len(数字)`时,(b)`num%b`,运气好,<`len(数字)`.例如,虽然`numbers`字符串的长度只有36个字符,但baseN(60,40)返回''1k',而baseN(79,40)引发`IndexError`.两者都应该引发某种错误.如果`not 2 <= base <= len(数字)`,则应修改代码以引发错误. (4认同)
  • @osa,我的观点是编写的代码以非常糟糕的方式失败(默默地,给出误导性答案)并且可以很容易地修复.如果你说如果事先知道肯定没有错误,那么`b`就不会超过`len(数字)`,祝你好运. (3认同)
  • 在这里使用短路似乎不必要地令人困惑……为什么不只使用 if 语句……行`return numerics[0] if num == 0 else baseN(num // b, b, numbers).lstrip (numerals[0]) + numbers[num % b]` 同样简短。 (2认同)

Ros*_*ost 73

"{0:b}".format(100) # bin: 1100100
"{0:x}".format(100) # hex: 64
"{0:o}".format(100) # oct: 144
Run Code Online (Sandbox Code Playgroud)

  • 但它只做那三个基地? (42认同)
  • 使用`hex(100)[2:]`,`oct(100)[2:]`和`bin(100)[2:]`可以得到相同的结果. (7认同)
  • @EvgeniSergeev:只有在 2.7/3.1+ 上才不需要。在 2.6 上,需要明确的位置(或名称)。 (3认同)
  • 是的,遗憾的是您无法指定自定义int基础.更多信息请访问:http://docs.python.org/library/string.html#formatstrings (2认同)
  • "0"是不必要的.这是Python 2文档:https://docs.python.org/2/library/string.html#format-string-syntax (2认同)

Mar*_*ing 21

很棒的答案!我想我的问题的答案是"不"我没有错过一些明显的解决方案.这是我将使用的功能,它浓缩了答案中表达的好主意.

  • 允许调用者提供的字符映射(允许base64编码)
  • 检查负数和零
  • 将复数映射到字符串元组

__PRE__

  • 如何将函数的base64输出转换回整数? (4认同)

Mik*_*ham 17

Python没有内置函数来在任意基础上打印整数.如果你愿意,你必须自己写.


sem*_*nte 14

您可以baseconv.py在我的项目中使用:https://github.com/semente/python-baseconv

样品用法:

>>> from baseconv import BaseConverter
>>> base20 = BaseConverter('0123456789abcdefghij')
>>> base20.encode(1234)
'31e'
>>> base20.decode('31e')
'1234'
>>> base20.encode(-1234)
'-31e'
>>> base20.decode('-31e')
'-1234'
>>> base11 = BaseConverter('0123456789-', sign='$')
>>> base11.encode('$1234')
'$-22'
>>> base11.decode('$-22')
'$1234'
Run Code Online (Sandbox Code Playgroud)

有一些bultin转换器,例如baseconv.base2,baseconv.base16baseconv.base64.


M.M*_*M.M 9

递归的

我想简化最投票回答到:

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

对于RuntimeError: maximum recursion depth exceeded in cmp非常大的整数和负数也有相同的建议。(您可以使用sys.setrecursionlimit(new_limit)

迭代式

为了避免递归问题

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

  • 精美的重构,并且没有库。 (2认同)

V. *_*rat 6

>>> numpy.base_repr(10, base=3) '101'


小智 5

def base(decimal ,base) :
    list = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    other_base = ""
    while decimal != 0 :
        other_base = list[decimal % base] + other_base
        decimal    = decimal / base
    if other_base == "":
        other_base = "0"
    return other_base

print base(31 ,16)
Run Code Online (Sandbox Code Playgroud)

输出:

「1F」


小智 5

def base_conversion(num, base):
    digits = []
    while num > 0:
        num, remainder = divmod(num, base)
        digits.append(remainder)
    return digits[::-1]
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

201189 次

最近记录:

6 年 前