【问题标题】:Pythonic way to do base conversionPythonic 进行基本转换的方法
【发布时间】:2015-03-03 05:41:42
【问题描述】:

我是 Python 的完全初学者。我编写了一些代码来执行基本转换,我想知道是否有更好的替代方案,它们的代码更短(单行)或更快。代码看起来很丑,感觉“非 Pythonic”,虽然作为初学者我不应该有任何这样的意见。任何改进代码的反馈将不胜感激。这纯粹是为了学习目的。

#!/usr/bin/env python

import math

def number_to_digits( number, radix ):
  'Converts a number into a vector of digits in given radix'
  digits = [0]*int(math.ceil(math.log(number,radix)))
  for ii in range(len(digits)):
    (number,digit) = divmod(number,radix)
    digits[ii] = digit
  return digits

def digits_to_number( digits, radix ):
  'Converts a vector of non-negative digits in given radix into a number'
  number = 0;
  for ii in range(len(digits)-1,-1,-1):
    number *= radix
    number += digits[ii]
  return number

if __name__ == '__main__':
  try:
    number = int(raw_input('Enter number: '))
    if number <= 0: raise ValueError()
    radix = int(raw_input('Enter radix: '))
    if radix <= 0: raise ValueError()
    digits = number_to_digits(number,radix)
    print digits
    number_again = digits_to_number(digits,radix)
    if not number_again == number:
      print 'test failed'
  except ValueError:
    print 'unexpected input'

终端上的示例会话产生:

Enter number: 44
Enter radix: 6
[2, 1, 1]

很容易检查 2 + 1*6 + 1*6**2 == 44。谢谢!

【问题讨论】:

    标签: python base-conversion


    【解决方案1】:

    这是一个很好的递归版本,可以从 Problem Solving with Algorithms and Data Structures 转换为十六进制

    def toStr(n,base):
        convertString = "0123456789ABCDEF"
        if n < base:
            return convertString[n]
        else:
            return toStr(n//base,base) + convertString[n%base]
    
    print(toStr(1453,16))
    

    【讨论】:

    • 再次,我不希望结果为字符串,但我了解您的递归实现,我会计时并发布结果。谢谢。
    • 要得到一个数组,运行 print(list(toStr(1453,16)))
    【解决方案2】:

    Python 提供了一些内置函数来将一个整数基数表示的值转换为另一个整数基数。整数有四种形式,即十进制、二进制、八进制和十六进制。

    Python 提供了内置的bin() 函数将非二进制数转换为二进制数,oct() 函数将非八进制数转换为八进制数和hex() 函数将非十六进制数转换为十六进制数。这些函数返回一个字符串文字来表示值。

    你可以从Integer base Conversion Functions in Python的教程中学习这些功能

    【讨论】:

      【解决方案3】:

      您可以在以下线程中找到(稍微)更简洁的示例: Python elegant inverse function of int(string,base).

      以排名靠前的例子为例,你可以稍微整理一下:

      def digit_to_char(digit):
          if digit < 10:
              return str(digit)
          return chr(ord('a') + digit - 10)
      
      def str_base(number, base):
          while number > 0:
              number, digit = divmod(number, base)
              yield digit_to_char(digit)
      

      结果:

      >>> list(str_base(44, 6))
      ['2', '1', '1']
      

      如果您不关心大于 10 的基数,则可以简化为:

      def str_base(number, base):
          if base > 10:
               raise ValueError('Base must be less than 10')
          while number > 0:
              number, digit = divmod(number, base)
              yield digit
      
      >>> list(str_base(44, 6))
      [2, 1, 1]
      

      【讨论】:

      • 我不想限制基数,我需要数字的数值来做进一步的处理,所以字符串转换是不必要的。您的生成器实现稍微干净一些,我确实需要列表形式的结果。我会计时,看看它是否更快并稍后发布结果。感谢您的意见。
      • 然后把yield digit_to_char(digit)改成yield digit
      猜你喜欢
      • 1970-01-01
      • 2013-09-19
      • 2015-07-28
      • 1970-01-01
      • 2010-11-27
      • 2019-01-25
      • 1970-01-01
      • 2019-03-08
      • 2018-05-27
      相关资源
      最近更新 更多