PythonAlgorithm

Pythonアルゴリズム入門に 『独学コンピューターサイエンティスト』

更新日:2022-11-08 公開日:2022-11-03

今回はコーリー・アルソフさんの『独学コンピューターサイエンティスト』を読み終えたので、その感想についてまとめていきます。

コーリー・アルソフさんといえば、Pythonの入門本として評判の高い『独学プログラマー』を著したことで有名。
ご存知の方も多いのではないでしょうか。
『独学プログラマー』自体は私も読んだことがあり、非常に素晴らしい本だったということもあり、気になって購入をしてみました。

書籍概要

前回の『独学プログラマー』がPythonの入門書だったのに対して、こちらはアルゴリズムの入門書といったところでしょうか。


1冊目としてちょうど良い難易度
本書の著者、コーリー・アルソフ(Cory Althoff)は、独学プログラマーです。前作『独学プログラマー』は、彼が独学で、ゼロからプログラミングを学んだ体験に基づいて書かれました。彼の独学プログラマーとしての学び方は、多くの人に支持されています。
前作のあとがきでも触れましたが、コーリー自身が学びの途中にあり、対象読者と同じ視点でアルゴリズムとデータ構造というコンピューターサイエンスの必須知識を説明してくれていることに価値があります。アルゴリズムとデータ構造を扱う本はたくさんありますが、本書ほど入門しやすく説明してくれている本は稀でしょう。
本書は、難しい内容であるアルゴリズムとデータ構造について、要点を絞って分かりやすく伝えています。そのため、これらを学ぶ1冊目としてちょうど良い難易度になっています。本書を読んだ後ならきっと、技術面接においてある程度の自信が持てるでしょうし、プログラムを実装する際にもキーワードとその内容を知っているので、文献探しや実装例を見つけ出す手がかりが得やすいでしょう。
――「日本語版あとがき」より

amazon.co.jpより引用


全体的な感想

結論から言ってアルゴリズムの入門書に最適な一冊だと感じました。
アルゴリズムというと難しい印象を受けますし、実際にちょっと読むのに気合がいるような難しい本が多い。
だけど、『独学コンピューターサイエンティスト』は本当に簡単な部分から入るので、あまり気構える必要はないです。
例えば、紹介されている線形サーチアルゴリズム。

def linear_search(a_list, n):
    for i in a_list:
        if i == n:
            return True
    return False

a_list = [1, 8, 32, 91, 5, 15, 9, 100, 3]
print(linear_search(a_list, 91))
>>>
True


この本ではこういう平易な例文を使用して、「もっと優れた方法はないか」ということを一緒に考えられるような構成になっています。

それと、入門というのに大事な要素は「その後もっと学ぶ気がおきるか」という点だと考えています。
このコーリー・アルソフさんはコーディングに対する発言がとてもかっこよく、刺激を受ける。
特にハッとさせられたのは冒頭の文章。

…たとえば、あなたの作ったウェブサイトは動作しているものの、そのコードはひどい出来かもしれません。コードの良し悪しを判断する基準がないのです。しかし、アルゴリズムを学んでいるときは違います。コンピューターサイエンスにはたくさんの有名なアルゴリズムがあります。自分の書いたコードと既存のアルゴリズムの実行結果を比べて、適切な結果を出せたかすぐに分かります。建設的なフィードバックを頻繁に受け続けることで、コーディングスキルが上達します。


良かったところ

以下、簡単に良かったと思ったところをまとめます。

標準ライブラリの知識が広がる

外部ライブラリを使わず、標準ライブラリを使用しているので、「こんな便利なものがあったのか」と気づかされました。
個人的にはbisectモジュールが汎用性が高いと感じました。
これを使うとソート済みのリストに対して素早く挿入されるべきインデックスを返してくれます。

from bisect import bisect_left 

sorted_fruits = ['apple', 'banana', 'orange', 'plum'] 
bisect_left(sorted_fruits, 'banana') 
>>> 
1 

bisect_left(sorted_fruits, 'kiwi' 
>>> 2


これを活用すると、二分探索も簡単に実装できます。

from bisect import bisect_left


def binary_search_w_bisect(an_iterable, target):
    index = bisect_left(an_iterable, target)
    if index <= len(an_iterable) and an_iterable[index] == target:
        return True
    return False


例文がかっこいい

これはコーリー・アルソフさんのセンスだと思うのですが、例文がかっこいいんですよね。
例えばリスト内の重複を見つけたい時にどうするでしょうか。

a_list = ['susan adams', 'kwame goodall', 'jill hampton', 'susan adams']


こういう時にsusan adamsを検出したいという例です。
色々な方法があると思います。
例えば辞書のキーの機能を使って回数を数えたりとか、リストのカウント機能をつかったりしてもできるかもしれません。
コーリー・アルソフさんは、setに重複した値を保持できない習性を活用してクールにこの問題を解決していました。

def return_dups(an_iterable):
    dups = []
    a_set = set()
    for item in an_iterable:
        l1 = len(a_set)
        a_set.add(item)
        l2 = len(a_set)
        if l1 == l2:
            dups.append(item)
    return dups


a_list = ['susan adams', 'kwame goodall', 'jill hampton', 'susan adams']
dups = return_dups(a_list)
print(dups)
>>>
['susan adams']


dupsという変数のつけ方もかっこよくていいですね。

引き出しが増える

いろいろな例が紹介されているので、使えるようになっておけばコーディング試験で役立つでしょう。
実際に私もpaizaやAtCoderの試験でお世話になったことがあります。

おわりに

アルゴリズムって楽しい!と思える良本でした。
おススメです。