python; checkio日記

checkioを中心にpythonプログラミングの記録

記念すべき第一問目: Home 問題1

pythonのプログラミング勉強をcheckioというHPの問題を作って勉強していきます。やったことを自分のメモ用に残しておきます。

お題

textの中に含まれるアルファベットの中で最も数が多いものを返す関数”checkio"を作れ
例) "mAkoshark!!!!"だったら、"a"

ポイント

  • 大文字小文字を区別しない
  • アルファベット以外は返さない
  • 同じ数あるものが複数あればアルファベット順で早い方を返す。

私が作ったのは下記です。

def checkio(text):
    test = [i for i in text.lower() if i.isalpha()]
    sortext = sorted(test)
    alphabet = []
    number = []
    prev = sortext[0]
    count = 0
    for i in range(len(sortext)):
        if i == len(sortext)-1: # last
            if sortext[i] == prev:
                count += 1
                number.append(count)
                alphabet.append(prev)
            else:
                alphabet.append(prev)
                number.append(count)
                alphabet.append(sortext[i])
                number.append(1)
        elif sortext[i] == prev:
            count += 1
        else:
            alphabet.append(prev)
            number.append(count)
            prev = sortext[i]
            count = 1
    ans1 = max(number)
    ans2 = np.array(alphabet)[np.array(number) == ans1][0]
    ans3 = ''.join(ans2)
    return ans3

まずテキストの中のアルファベットのみを抜き出して小文字にして、並べ替え、それを前から数えていくという方法を取りましたが、問題は終わり方で、そこだけ別の場合分けをする必要がありました。長いです。。。

他の方がよく使っているのは、collectionsライブラリーのCounterという関数で、これを使うと
Counter({'a': 2, 'h': 1, 'k': 2, 'm': 1, 'o': 1, 'r': 1, 's': 1})
という風に、数えてくれるようです。

from collections import Counter
def checkio(text):
    test = [i for i in text.lower() if i.isalpha()]
    count = Counter(test)
    maxch = max(count.values())
    return [x for (x, y) in count.items() if y == maxch][0]

あとは 小文字にするところで、下記のようなものを使っている人もいました。filterは一つ目の引数でTrueのみに2つ目の処理を施すということだそうです。直線的な考えでいいですね。

test = list(filter(str.isalpha, text.lower()))

lambdeと組み合わせて使うことで直線的なプログラミングをする時に使うそうです。

xs = range(10)
list(filter(lambda x: x**2 > 25, xs))

ちなみに、このfilter部分をmapに変えると、xs全てにlambdaを適用した結果が帰ります。便利!