Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/63.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python优雅的int反函数(字符串,基)_Python - Fatal编程技术网

Python优雅的int反函数(字符串,基)

Python优雅的int反函数(字符串,基),python,Python,python允许使用[2,36]范围内的任何基将字符串转换为整数,使用: int(string,base) 我正在寻找一个优雅的反函数,它接受一个整数和一个基数,并返回一个字符串 比如说 >>> str_base(224,15) 'ee' 我有以下解决方案: def digit_to_char(digit): if digit < 10: return chr(ord('0') + digit) else: return chr(ord('a') +

python允许使用[2,36]范围内的任何基将字符串转换为整数,使用:

int(string,base)
我正在寻找一个优雅的反函数,它接受一个整数和一个基数,并返回一个字符串

比如说

>>> str_base(224,15)
'ee'
我有以下解决方案:

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)
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()
def digit_到_char(数字):
如果数字<10:返回chr(ord('0')+数字)
其他:返回chr(ord('a')+数字-10)
def str_底座(编号、底座):
如果数字<0:
返回'-'+str_base(-number,base)
其他:
(d,m)=divmod(数字,基数)
如果d:
返回str_base(d,base)+digital_到_char(m)
其他:
将数字_返回到字符(m)
注意:digit_to_char()用于base有一些示例实现

事实上,我认为你的解决方案看起来相当不错,它甚至是递归的,这在这里是令人愉快的

我仍然会简化它以删除
else
,但这可能是一种个人风格。我认为
if foo:return
非常清晰,不需要在它后面加
else
来明确它是一个单独的分支

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)
def digit_到_char(数字):
如果数字<10:
返回str(数字)
返回chr(ord('a')+数字-10)
def str_底座(编号、底座):
如果数字<0:
返回'-'+str_base(-number,base)
(d,m)=divmod(数字,基数)
如果d>0:
返回str_base(d,base)+digital_到_char(m)
将数字_返回到字符(m)

我将0-9的大小写简化为char(),我认为
str()
chr(ord())
结构更清晰。为了最大限度地利用
=10
的对称性,可以将
ord()
分解出来,但我没有费心,因为它会增加一行,简洁性会更好。:)

数字字符
可以这样实现:

def digit_to_char(digit):
    return (string.digits + string.lowercase)[digit]
回顾这一点

def int2str(num, base=16, sbl=None):
    if not sbl:
        sbl = '0123456789abcdefghijklmnopqrstuvwxyz'
    if len(sbl) < 2:
        raise ValueError, 'size of symbols should be >= 2'
    if base < 2 or base > len(sbl):
        raise ValueError, 'base must be in range 2-%d' % (len(sbl))

    neg = False
    if num < 0:
        neg = True
        num = -num

    num, rem = divmod(num, base)
    ret = ''
    while num:
        ret = sbl[rem] + ret
        num, rem = divmod(num, base)
    ret = ('-' if neg else '') + sbl[rem] + ret

    return ret
def int2str(num,base=16,sbl=None):
如果不是sbl:
sbl='0123456789abcdefghijklmnopqrstuvwxyz'
如果len(sbl)<2:
raise VALUERROR,“符号大小应大于等于2”
如果基准<2或基准>长度(sbl):
raise VALUERROR,'基必须在范围2-%d'(len(sbl))
负=假
如果num<0:
负=真
num=-num
num,rem=divmod(num,base)
ret=''
而num:
ret=sbl[rem]+ret
num,rem=divmod(num,base)
ret=('-'如果没有其他')+sbl[rem]+ret
回程网

也许这不应该是一个答案,但它可能对某些人有帮助:内置函数确实可以在几个基数中将数字转换为字符串:

>>> format(255, 'b') # base 2
'11111111'
>>> format(255, 'd') # base 10
'255'
>>> format(255, 'o') # base 8
'377'
>>> format(255, 'x') # base 16
'ff'

如果您使用Numpy,则有


您可以在下阅读代码。简短而优雅

以上的答案真的很好。这对我用C语言实现一个算法原型帮助很大

我想做一点修改(我以前用过),将十进制转换为符号空间的基数

我也忽略了负数值,只是为了简短和数学上的错误 -->模块算术的其他规则 -->如果在无符号和有符号值中使用二进制、oct或十六进制-->差异,则使用其他数学

def str_base(number, base):
   (d,m) = divmod(number,len(base))
   if d > 0:
      return str_base(d,base)+base[m]
   return base[m]
这导致了以下输出

>>> 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'
如果您想使用propper零符号填充,可以使用

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'
以下是我的解决方案:

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)
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*基数**2+a3*基数**3…
。“任务”是找到所有的a

对于每个
N=1,2,3…
,代码通过b对
b=base**(N+1)
进行“moudiling”来隔离
aN*base**N
,b=base**(N+1)对所有大于N的a进行切片,并通过每次当前
aN*base**N
调用函数时减少a来对序列小于N的所有a进行切片

Base%(Base-1)==1
因此
Base**p%(Base-1)==1
因此
q*Base^p%(Base-1)==q
只有一个异常,当
q=Base-1
返回
0
。 为了解决这个问题,如果它返回
0
,函数从一开始就检查它是否
0


优势
在这个示例中,只有一个乘法(而不是除法)和一些模的实例需要相对较少的时间。

我曾经用同样的目标编写过自己的函数,但现在复杂得令人尴尬

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))
来自数学导入日志、ceil、floor
从集合导入deque
从itertools导入重复
从字符串导入大写字母,数字
进口稀土
__字母数字=(数字+大写)
类InvalidBaseError(ValueError):通过
类FloatConvertError(ValueError):通过
类IncorrectBaseError(ValueError):通过
def getbase(数字,base=2,frombase=10):
如果不是frombase==10:
number=getvalue(number,frombase)
#getvalue也是一个复制int(number,base)的个人函数
如果1>=底座或底座>=长度(_字母数字)或非地板(底座)==底座:
raise INVALIIDBASERROR(“无效值:{}作为要转换的基输入
到。\n{}。格式(基,
“断言要转换为的基是十进制整数。”)
如果存在(编号,str):
尝试:
编号=atof(编号)
除值错误外:
#如果第一次检查基数是否为10,则已经更正了该数字
raise INCORRECTBASERROR(“作为数字的基数传递的基数不正确->数字:{}基数:{}”。格式(数字,frombase))
#^v支持浮点数,因为该数是另一个操作的返回
如果编号>楼层(编号):
raise FloatConvertError(“要转换的数字不能是浮点。{}”。格式(数字))
isNegative=False
如果数字<0:
isNegative=True
数字=abs(数字)
对数=对数(数字,基数),如果数字为0#轻松绕过数字为零
上限=整数(对数)+1
结构=天花板(重复(0,天花板),最大=天花板)
而编号:
如果数字>=(基数**整数(对数)):
可接受的数字=
>>> timeit.timeit(lambda: [int2base(n, 36) for n in range(10000)], number=1000)
4.883068453882515
def encode(nIn, nBase):
   n = nIn // nBase
   s = '0123456789abcdefghijklmnopqrstuvwxyz'[nIn % nBase]
   return encode(n, nBase) + s if n > 0 else s

n = 1577858399
s = encode(n, 36)
print(s == 'q3ezbz')