Когда-то я написал свою собственную функцию с той же целью, но теперь это невероятно сложно.
from math import log, ceil, floor
from collections import deque
from itertools import repeat
from string import uppercase, digits
import re
__alphanumerals = (digits + uppercase)
class InvalidBaseError(ValueError): pass
class FloatConvertError(ValueError): pass
class IncorrectBaseError(ValueError): pass
def getbase(number, base=2, frombase = 10):
if not frombase == 10:
number = getvalue(number, frombase)
#getvalue is also a personal function to replicate int(number, base)
if 1 >= base or base >= len(__alphanumerals) or not floor(base) == base:
raise InvalidBaseError("Invalid value: {} entered as base to convert
to. \n{}".format(base,
"Assert that the base to convert to is a decimal integer."))
if isinstance(number, str):
try:
number = atof(number)
except ValueError:
#The first check of whether the base is 10 would have already corrected the number
raise IncorrectBaseError("Incorrect base passed as base of number -> number: {} base: {}".format(number, frombase))
#^ v was supporting float numbers incase number was the return of another operation
if number > floor(number):
raise FloatConvertError("The number to be converted must not be a float. {}".format(number))
isNegative = False
if number < 0:
isNegative = True
number = abs(number)
logarithm = log(number, base) if number else 0 #get around number being zero easily
ceiling = int(logarithm) + 1
structure = deque(repeat(0, ceiling), maxlen = ceiling)
while number:
if number >= (base ** int(logarithm)):
acceptable_digit = int(number / (base ** floor(logarithm)))
structure.append(acceptable_digit if acceptable_digit < 10 else __alphanumerals[acceptable_digit])
number -= acceptable_digit * (base ** floor(logarithm))
else:
structure.append(0)
logarithm -= 1
while structure[0] == 0:
#the result needs trailing zeros
structure.rotate(-1)
return ("-" if isNegative and number else "") + reduce(lambda a, b: a + b, map(lambda a: str(a), structure))
Я думаю, однако, что функция strbase должна поддерживать только базы> = 2 и <= 36, чтобы предотвратить конфликт с другими инструментами в python, такими как int.
Кроме того, я думаю, что для предотвращения конфликта с другими функциями, такими как int, следует использовать только один регистр алфавитов, предпочтительно снова в верхнем регистре, поскольку он будет считать «a» и «A» равными 10. </p>
from string import uppercase
dig_to_chr = lambda num: str(num) if num < 10 else uppercase[num - 10]
def strbase(number, base):
if not 2 <= base <= 36:
raise ValueError("Base to convert to must be >= 2 and <= 36")
if number < 0:
return "-" + strbase(-number, base)
d, m = divmod(number, base)
if d:
return strbase(d, base) + dig_to_chr(m)
return dig_to_chr(m)