Pythonで数値とアルファベットを何桁でも相互変換する方法

こんにちは、データサイエンティストのたぬ(@tanuhack)です!

PythonでCSVやエクセル、スプレッドシートを操作するとき、『数値→アルファベット』や『アルファベット→数値』の変換を実現させたいときってありませんか?

例:数値→アルファベット
1→A、26→Z、27→AA、1000→ALL
例:アルファベット→数値
A→1、Z→26、AA→27、ALL→1000

1桁の相互変換であれば、Pythonの組み込み関数(ordchr)とラムダ関数を使えば1行で実現出来ます。

# 数値(1〜26)→アルファベット(A〜Z)
num2alpha = lambda c: chr(c+64)

num2alpha(3) #==> C 
# アルファベット(A〜Z)→数値(1〜26)
alpha2num = lambda c: ord(c) - ord('A') + 1

alpha2num('Y') #==> 25 

しかし、このままだと2桁や3桁など複数の桁に対応できないので汎用性が低いです。

そこで今回は、数値とアルファベットを何桁でも相互変換できる方法を紹介します。

アルファベットから数値に変換する

# アルファベット→数値
def alpha2num(alpha):
    num=0
    for index, item in enumerate(list(alpha)):
        num += pow(26,len(alpha)-index-1)*(ord(item)-ord('A')+1)
    return num
関数名 説明 実行例
alpha2num(alpha) アルファベットを数値に変換する alpha2num('AA')→27

アルゴリズム

アルファベットから数値の変換は26進数→10進数的な考え方を使います。

例えば、『ALL』という文字列を数値に変換させる場合、

  1. 『ALL』を『A』、『L』、『L』と1文字ずつに分解
  2. 『A』、『L』、『L』を桁数に応じて、10進数に変換
  3. (26^2)*A + (26^1)*L + (26^0)*L => (26^2)*1 + (26^1)*12 + (26^0)*12 => 1000

と、Forループを使って算出します。

数値からアルファベットに変換する

# 数値→アルファベット
def num2alpha(num):
    if num<=26:
        return chr(64+num)
    elif num%26==0:
        return num2alpha(num//26-1)+chr(90)
    else:
        return num2alpha(num//26)+chr(64+num%26)
関数名 説明 実行例
num2alpha(num) 数値をアルファベットに変換する num2alpha(27)→AA

アルゴリズム

数値からアルファベットの変換は10進数→26進数的な考え方を使います。

例えば、『1000』という数値をアルファベットに変換させる場合、

  1. 26のn乗で1000以下の最大のnを求める→『n+1』がアルファベットの桁数、n=2
  2. (26^2)*xで1000以下の最大のxを求める→x=1、つまり3桁目のアルファベットはA
  3. (26^1)*yで1000-(26^2)*1=324以下の最大のyを求める→y=12、つまり2桁目のアルファベットはL
  4. (26^0)*z=12→つまり3桁目のアルファベットはL、ゆえに1000はALL

と、再帰を使って算出します。

さいごに

今回は、何桁でも相互変換可能な数値とアルファベット間のやりとりについて紹介しました。

CSVやエクセル、スプレッドシートなどいろんなことに役立ててください(^^)

それでは〜