ふとある時、カタカナ単語を五十音順(≒辞書配列順)にソートしてくれる機能が欲しくなってコーディングし始めました。
しかし、よくよく調べてみたら、Pythonの配列に「sort」メソッドがあるではありませんか・・・(笑)。
とんだ「再発明」をしてしまいました・・・(泣)。
でもせっかくなので、自分で書いたコードをQiitaの記事にしてしまおうと考えたワケです(爆)。
よかったら、ご自分の環境で実行して(みるまでもないか)・・・。
(どうせ、「sort」メソッドとほとんど結果は変わらないし)。
もしも、Python標準の「sort」メソッドと挙動や結果が違う部分があったら報告してみてください。
(多分、変更しませんが・・・)。
kana_sort.py
# coding: utf-8
#各モジュールの読み込み
import sys
import numpy
#ソート処理する各文字列の最大の長さ
#(実際には、配列に1文字ずつ格納するので「1行分の要素数」と等価)
CHRS_MAX_NUM = 10
#日本語のカナ文字から一意の数値へと変換するための辞書
kana_to_num_dict = {"ア":1, "ァ":2, "イ":3, "ィ":4, "ウ":5, "ゥ":6, "エ":7, "ェ":8, "オ":9, "ォ":10, \
"カ":11, "ガ":12, "キ":13, "ギ":14, "ク":15, "グ":16, "ケ":17, "ゲ":18, "コ":19, "ゴ":20, \
"サ":21, "ザ":22, "シ":23, "ジ":24, "ス":25, "ズ":26, "セ":27, "ゼ":28, "ソ":29, "ゾ":30, \
"タ":31, "ダ":32, "チ":33, "ヂ":34, "ツ":35, "ッ":36, "ヅ":37, "テ":38, "デ":39, "ト":40, "ド":41, \
"ナ":42, "ニ":43, "ヌ":44, "ネ":45, "ノ":46, \
"ハ":47, "バ":48, "パ":49, "ヒ":50, "ビ":51, "ピ":52, "フ":53, "ブ":54, "プ":55, "ヘ":56, "ベ":57, "ペ":58, "ホ":59, "ボ":60, "ポ":61, \
"マ":62, "ミ":63, "ム":64, "メ":65, "モ":66, \
"ヤ":67, "ャ":68, "ユ": 69, "ュ":70, "ヨ":71, "ョ":72, \
"ラ":73, "リ":74, "ル":75, "レ":76, "ロ":77, \
"ワ":78, "ヲ":79, "ン":80, \
"ー":81, "*":99}
#一意の数値から日本語のカナ文字へと変換するための辞書
num_to_kana_dict = {1:"ア", 2:"ァ", 3:"イ", 4:"ィ", 5:"ウ", 6:"ゥ", 7:"エ", 8:"ェ", 9:"オ", 10:"ォ", \
11:"カ", 12:"ガ", 13:"キ", 14:"ギ", 15:"ク", 16:"グ", 17:"ケ", 18:"ゲ", 19:"コ", 20:"ゴ", \
21:"サ", 22:"ザ", 23:"シ", 24:"ジ", 25:"ス", 26:"ズ", 27:"セ", 28:"ゼ", 29:"ソ", 30:"ゾ", \
31:"タ", 32:"ダ", 33:"チ", 34:"ヂ", 35:"ツ", 36:"ッ", 37:"ヅ", 38:"テ", 39:"デ", 40:"ト", 41:"ド", \
42:"ナ", 43:"ニ", 44:"ヌ", 45:"ネ", 46:"ノ", \
47:"ハ", 48:"バ", 49:"パ", 50:"ヒ", 51:"ビ", 52:"ピ", 53:"フ", 54:"ブ", 55:"プ", 56:"ヘ", 57:"ベ", 58:"ペ", 59:"ホ", 60:"ボ", 61:"ポ", \
62:"マ", 63:"ミ", 64:"ム", 65:"メ", 66:"モ", \
67:"ヤ", 68:"ャ", 69:"ユ", 70:"ュ", 71:"ヨ", 72:"ョ", \
73:"ラ", 74:"リ", 75:"ル", 76:"レ", 77:"ロ", \
78:"ワ", 79:"ヲ", 80:"ン", \
81:"ー", 99:"*"}
#「kana_wrds」という名前のNumpy形式の配列を操作するための添字
#(「while」文の中で用いる)
i = 0
j = 0
#「kana_wrds」という名前のNumpy形式の配列を操作するための添字
#(「for」文の中で用いる)
item_num = 0
items_num = 0
#コマンドライン引数が代入されるNumpy形式の配列
argv = numpy.empty((len(sys.argv)-1, CHRS_MAX_NUM), dtype=object)
#「argv」の内容が1文字づつコピーされて、かつ、カナから数値へと変換されて格納される配列
kana_wrds = numpy.empty((len(sys.argv)-1, CHRS_MAX_NUM), dtype=object)
#Numpy形式の配列の行を交換するための一時的な配列
swap_row1 = []
swap_row2 = []
#配列に1文字づつ格納されている各文字を連結するためのもの
kana_str = ""
#文字数をカウントするためのもの
chrs_cnt = 0
#最終的な結果を格納するための配列
kana_wrds_final = []
if len(sys.argv)-1 == 0:
print("コマンドライン引数が無いです。最少でも2個以上入力してください。")
sys.exit(1)
if len(sys.argv)-1 == 1:
print("コマンドライン引数が少ないです。最少でも2個以上入力してください。")
sys.exit(1)
for items in sys.argv:
for item in items:
if (i > 0):
argv[i-1][j] = item
j += 1
else:
i += 1
j = 0
else:
i = 0
j = 0
for items in argv:
for item in items:
kana_wrds[i][j] = item
j += 1
else:
i += 1
j = 0
numpy.putmask(kana_wrds, kana_wrds == None, "*")
for items in kana_wrds:
for item in items:
try:
kana_wrds[items_num][item_num] = kana_to_num_dict[item]
except KeyError:
print("対応していない文字が入力されています。")
sys.exit(1)
except IndexError:
print("文字数の制限を超えて入力されています。")
sys.exit(1)
item_num += 1
else:
item_num = 0
items_num += 1
else:
item_num = 0
items_num = 0
print("----------------------------------------------------------------------")
print(kana_wrds)
print("----------------------------------------------------------------------")
i = 0
j = kana_wrds.shape[1]-1
while j > -1:
while i+1 < kana_wrds.shape[0]:
if (kana_wrds[i][j] != 99 and kana_wrds[i+1][j] != 99):
if kana_wrds[i][j] > kana_wrds[i+1][j]:
print("swap!")
print(kana_wrds[i])
print(kana_wrds[i+1])
swap_row1 = kana_wrds[i].copy()
swap_row2 = kana_wrds[i+1].copy()
kana_wrds[i+1] = swap_row1
kana_wrds[i] = swap_row2
print(kana_wrds[i])
print(kana_wrds[i+1])
i = 0
continue
if kana_wrds[i][j] < kana_wrds[i+1][j]:
print("pass...")
i += 1
continue
if kana_wrds[i][j] == kana_wrds[i+1][j]:
print("pass...")
i += 1
continue
if (kana_wrds[i][j] != 99 and kana_wrds[i+1][j] == 99):
print("swap!")
print(kana_wrds[i])
print(kana_wrds[i+1])
swap_row1 = kana_wrds[i].copy()
swap_row2 = kana_wrds[i+1].copy()
kana_wrds[i+1] = swap_row1
kana_wrds[i] = swap_row2
print(kana_wrds[i])
print(kana_wrds[i+1])
i = 0
continue
if (kana_wrds[i][j] == 99 and kana_wrds[i+1][j] != 99):
print("pass...")
i += 1
continue
if (kana_wrds[i][j] == 99 and kana_wrds[i+1][j] == 99):
print("pass...")
i += 1
continue
else:
i = 0
j -= 1
print("----------------------------------------------------------------------")
print(kana_wrds)
print("----------------------------------------------------------------------")
for items in kana_wrds:
item_num = 0
for item in items:
kana_wrds[items_num][item_num] = num_to_kana_dict[item]
item_num += 1
else:
items_num += 1
for items in kana_wrds:
for item in items:
if item != "*":
kana_str += item
if (item == "*" and kana_str == ""):
break
if chrs_cnt == kana_wrds.shape[1]-1:
kana_wrds_final.append(kana_str)
kana_str = ""
chrs_cnt = 0
break
chrs_cnt += 1
print(kana_wrds_final)
念のため、実行用のWindowsバッチファイルも載せておきます。
appexcec__kana_sort.bat
cd C:\Users\name\Documents←「name」=ご自身の名前。
chcp 65001←コマンドプロンプト上の文字コード変更。
py kana_sort.py ギョーザ ギヨウザ ギョザ ギョウザ←この要領で引数を与えてやります。
pause←これがないと実行し始めてから一瞬でウインドウが消えてしまいます。
いかがでしたでしょうか?。
PYthon標準の「sort」メソッドであれば、当然、文字コードを使っているはずです。
しかし、筆者は文字コードのことはチンプンカンプンなので、独自の文字コード(?)を使って実装してみました。
また、懲りずに記事を書いていきたいと思います。
それではまた~。