Python elegant inverse function of int(string,base)
python allows conversions from string to integer using any base in the range [2,36] using:
int(string,base)
im looking for an elegant inverse function that takes an integer and a base and returns a string
for example
>>> str_base(224,15)
'ee'
i have the following solution:
def digit_to_char(digit):
if digit < 10: return chr(ord('0') + digit)
else: return chr(ord('a') + digit - 10)
def str_base(number,base):
if number < 0:
return '-' + str_base(-number,base)
else:
(d,m) = divmod(number,base)
if d:
return str_base(d,base) + digit_to_char(m)
else:
return digit_to_char(m)
note: digit_to_char() works for bases <= 169 arbitrarily using ascii characters after 'z' as digits for bases above 36
is there a python builtin, library function, or a more elegant inverse function of int(string,base) ?
Maybe this shouldn't be an answer, but it could be helpful for some: the built-in format
function does convert numbers to string in a few bases:
>>> format(255, 'b') # base 2
'11111111'
>>> format(255, 'd') # base 10
'255'
>>> format(255, 'o') # base 8
'377'
>>> format(255, 'x') # base 16
'ff'
If you use Numpy, there is numpy.base_repr
.
You can read the code under numpy/core/numeric.py
. Short and elegant
This thread has some example implementations.
Actually I think your solution looks rather nice, it's even recursive which is somehow pleasing here.
I'd still simplify it to remove the else
, but that's probably a personal style thing. I think if foo: return
is very clear, and doesn't need an else
after it to make it clear it's a separate branch.
def digit_to_char(digit):
if digit < 10:
return str(digit)
return chr(ord('a') + digit - 10)
def str_base(number,base):
if number < 0:
return '-' + str_base(-number, base)
(d, m) = divmod(number, base)
if d > 0:
return str_base(d, base) + digit_to_char(m)
return digit_to_char(m)
I simplified the 0-9 case in digit_to_char()
, I think str()
is clearer than the chr(ord())
construct. To maximize the symmetry with the >= 10
case an ord()
could be factored out, but I didn't bother since it would add a line and brevity felt better. :)
The above answers are really nice. It helped me a lot to prototype an algortithm I had to implement in C
I'd like to come up with a little change (I used) to convert decimal to a base of symbolspace
I also ignored negativ values just for shortness and the fact that's mathematical incorrect --> other rules for modular arithmetics --> other math if you use binary, oct or hex --> diff in unsigned & signed values
def str_base(number, base):
(d,m) = divmod(number,len(base))
if d > 0:
return str_base(d,base)+base[m]
return base[m]
that lead's to following output
>>> str_base(13,'01')
'1101'
>>> str_base(255,'01')
'11111111'
>>> str_base(255,'01234567')
'377'
>>> str_base(255,'0123456789')
'255'
>>> str_base(255,'0123456789abcdef')
'ff'
>>> str_base(1399871903,'_helowrd')
'hello_world'
if you want to padd with the propper zero symbol you can use
symbol_space = 'abcdest'
>>> str_base(734,symbol_space).rjust(0,symbol_space[0])
'catt'
>>> str_base(734,symbol_space).rjust(6,symbol_space[0])
'aacatt'