見出し画像

CourseraでPython Data Structuresを受講した(後編)

こんにちは、からあげです。ミシガン大学がCoursera上で開講しているオンライン講座"Python for Everybody"の第2コース、”Python Data Structures"の講義メモの後編です。

第2コース前半の講義録はこちらからどうぞ↓


1.Week 4

<テキストの範囲>
Chapter 8: Lists

いよいよ、Pythonプログラミングも第2コースの中盤に差し掛かり、アルゴリズムの話から始まります。アルゴリズムとは、問題を解くために使われるルールや手順のセットを言い、データ・ストラクチャとはコンピューターの中にあるデータを組織する特定の方法を指します。

コレクションとは、複数の値を持つ変数です。以前にも、文字列のセットを次のように定義しました。

friends = ['Joseph', 'Glenn', 'Sally']

このように、[ ]カッコで括られ、それぞれの要素(element)がカンマで区切られる一連のセットをリストと呼びます。

リストの中にある要素は、上書き可能(mutable)です。この性質は重要ですので覚えておきましょう。

a = [5, 7, 3, 8, 'Q']
a[2] = 'J' #...[1]
print(a)

このように、リストの一部を上書きすることができます。[1]では、3番目の要素が上書きされます。

[5, 7, 'J', 8, 'Q']

for文を用いた場合、カウンタはリストに含まれる要素そのものを順番に参照します。

a = [5, 7, 3, 8, 'Q']
for i in a: #...[1]
    print(i, a[i])
for i in range(len(a)): #...[2]
    print(i, a[i])

1回目のループ[1]と、2回目のループ[2]の違いは、カウンタとして定義しているiの挙動です。1回目はaにある要素そのものをiに代入していきますが、2回目はrange(len(a))によって、リスト[0, 1, 2, 3, 4]に変換します。したがって出力結果は、

5 5
7 7
3 3
8 8
Q Q
0 5
1 7
2 3
3 8
4 Q

となります。

次に、リストの操作を学びましょう。リストを連結するには、+を使います。要素同士を足し算するのではないので気をつけましょう。また、文字列と同様、リストの一部を切り出すときは[a: b]としますが、後者のbはその要素を含みません。[1:5]であれば、リストの[1]から[4]までが切り出される範囲となります。

t = [2, 3, 5, 7, 11, 13, 17, 19]
t[1:4] #...[1]
t[:5] #...[2]

[1]では、[3, 5, 7]が切り出され、[2]では、[2, 3, 5, 7, 11]までが切り出されます。

次に、空のリストを定義し、そこから要素を追加していく操作を見ていきましょう。

stuff = list() #...[1]
stuff.append('Billy') #...[2]
stuff.append('Michael')
stuff.append(94)
print(stuff)

[1]で、空のリストstuffを定義します。次に、append()のカッコの中に要素となるデータを書いていきます。なおリストは文字列だけでなく、数値との混在も可能です。

['Billy', 'Michael', 94]

リストの要素をアルファベット順に並べ替えるには、sort()を用います。

str_name = ['Peter', 'Glenn', 'Joseph']
str_name.sort() #...[1]
print(str_name)

[1]のようにリスト.sort()を命令すると、リストの順序をA→Zの順に並べ替えてくれます。文字の数が小さい順ではありませんので注意してください。

['Glenn', 'Joseph', 'Peter']

文字列を単語に区切る処理を見ていきましょう。スペースで区切られた文章を単語に区切るには、split()を用います。

abc = 'I am not sick'
words = abc.split() #...[1]
print(words)
print(words[1]) #...[2]

[1]で、wordsというリストに文字列abcから空白で区切られた単語を切り出します。wordsはリスト形式ですので、[2]のように各要素を1つだけ抜き出して表示することもできます。

['I', 'am', 'not', 'sick']
am

split()は複数の空白が含まれていても、空白を含まない形式の単語に正しく抜き出されます。空白ではなく;などの別の文字で単語が区切られている場合は、split(';')のようにカッコの中に区切るべき文字を含めてください。

さて、次は少し実用的なコードになります。メールのヘッダーに含まれるFromの行から送信元のメールアドレスを抜き出し、さらにはホスト名を抜き出すという操作をしてみましょう。前回行ったfind()を用いた文字列操作よりも簡単にできます。

data = 'From koreha_sample_desuyo@kyoko-u.ac.jp pSat Jun 6 02:03:34 2015'
words = data.split() #...[1]
email_address = words[1] #...[2]
email_pieces = email_address.split('@') #...[3]
print(email_pieces[1])

[1]ではまず空白で区切られているものを切り出し、wordsリストに格納します。[2]で、wordsリストの2番目にあるメールアドレスをemail_addressに文字列として格納します。[3]で、@を区切りとしてemail_piecesリストに要素を格納します。ホスト名は2番目の要素ですから、email_pieces[1]が取り出したいホスト名になります。


2.Week 5

<テキストの範囲>
Chapter 9: Dictionaries

続いて、ディクショナリを見ていきましょう。ディクショナリはPHPなどの言語では連想配列(associative array)とも言われ、データベースのようにキーと値の2つのセットで構成されます。

空のディクショナリを作成するには、リストと同様、変数の定義段階でdict()を用います。キーと値は、リストのように番号ではなく文字を指定することができます。

data = dict()
data['Sarah'] = 40
data['Mike'] = 25
data['Judy'] = 99
print(data)
data['Mike'] = data['Mike'] + 8 #...[1]
print(data['Mike'])

ディクショナリは、表示される際に{ }というカッコで括られ、キー、コロン、値の順に表示されます。[1]のように、特定のキーを持つ値を変更させることもできます。

{'Sarah': 40, 'Mike': 25, 'Judy': 99}
33

次に、最も頻度の高い単語が何かを、ヒストグラムによって確認する方法を学びましょう。ディクショナリを用いて、ディクショナリに既にある単語が見つかれば値を1増やし、ディクショナリにない単語が見つかれば値を初期値の1とします。

counts = dict()
names = ['Tom', 'Sam', 'Jim', 'Chang', 'Sam']
for name in names: #...[1]
    if name not in counts: #...[2]
        counts[name] = 1
    else: #...[3]
        counts[name] = counts[name] + 1
print(counts)

ここでは、countsをディクショナリとして、countsにキーと値を格納していきます。[1]では、検索対象となる文字列の順番に変数nameを動かしていきます。[2]では、countsディクショナリにnameというキーが登録されているかを判断します。not inですから、登録されていなければTrue、登録されていなければ[3]を実行します。[3]は、countsディクショナリの中にある該当する名前に対応する値を1増やします。出力結果は、以下のとおりになります。

{'Tom': 1, 'Sam': 2, 'Jim': 1, 'Chang': 1}

ここで、[2]と[3]の処理を一行で済ませる便利なgetメソッドを紹介しましょう。getメソッドは、ディクショナリにキーがなければ登録し、初期値を値に代入します。ディクショナリにキーがあれば、その値を返します。

counts = dict()
names = ['Tom', 'Sam', 'Jim', 'Chang', 'Sam']
for name in names:
    counts[name] = counts.get(name, 0) + 1 #...[1]
print(counts)

これにより、ぐっとコードの行数は減りました。[1]のgetメソッドでは、ディクショナリにキーがない場合は右辺第1項は0、第2項が1ですから、1が格納されることになります。キーがある場合は、値に1を加える操作をしています。出力結果は、先のものと同じです。

次に、ディクショナリのキーだけ、または値だけを抜き出す方法を見ていきましょう。

a = {'Sarah': 40, 'Mike': 25, 'Judy': 99}
print(list(a)) #...[1a]
print(a.keys()) #...[1b]
print(a.values()) #...[2]
print(a.items()) #...[3]

[1a]と[1b]は同じように、キーのリストを返します。[2]は値のみを抜き出します。[3]はタプル形式で表示します。[3]については次の講義で明らかになりますが、forループなどでキーと値のペアごとカウンタにしてしまうという使い方ができる機能です。表示結果は以下のとおりです。

['Sarah', 'Mike', 'Judy']
['Sarah', 'Mike', 'Judy']
[40, 25, 99]
[('Sarah', 40), ('Mike', 25), ('Judy', 99)]

さて、いよいよファイルやディクショナリを活用した実用的なプログラムを書いていきましょう。

name = input('Enter file name:') #...[1]
handle = open(name)

counts = dict() #...[2]
for line in handle:
    words = line.split()
    for word in words:
        counts[word] = counts.get(word, 0) + 1

bigcount = None #...[3]
bigword = None
for word, count in counts.items():
    if bigcount is None or count > bigcount:
        bigword = word
        bigcount = count

print(bigword, bigcount)

このプログラムは、大きく分けて3つの機能を持っています。まず[1]でファイル名を指定して、ファイルを開きます。
[2]で、1行ごとにファイルを読んで、空白によって区切られている単語をバラバラに分解し、wordsリストに格納します。そして、countsディクショナリによって、単語をキーとして出現回数を値にカウントしていきます。
[3]で、countsディクショナリに出来たヒストグラム(のようなもの)を順に見ていき、最も多く出てきた単語かどうかを判定し、最も多く出てきた単語をbigword、回数をbigcountに代入します。

[3]にあるfor文は少し分かりにくいですが、word, countという2つの変数ごとカウンタにしてしまっています。つまり、例で言えば

word変数, count変数の変化・・・('Sarah', 40)→('Mike', 25)→('Judy', 99)

というように変化していく操作になっています。


3.Week 6

<テキストの範囲>
Chapter 10: Tuples

タプルは、リストのようなものですが、大きな違いはリストのように要素の変更をすることができません。並べ替えsort()も追加append()も逆順並び替えreverse()もできません。

その代わり、通常は変数は左辺側には1つしか指定できませんでしたが、タプルは複数の変数を一度に代入することができます。

(x, y) = (5, 'Japanese')
print(y)

ここで、出力結果は、

Japanese

となります。

タプルは不等式で比較することができます。1番目、2番目、3番目・・・のように要素同士で比較されます。文字列であれば、アルファベットのAからZの順に大きくなっていきます。

(0, 3, 7) < (5, 2, 1)
(0, 0, 3) < (0, 0, 4)

タプルはキーの順序にソートすることができます。ディクショナリ形式のデータをソートするには、sorted()を用います。

d = {'b': 1, 'c':22, 'a': 10}
d.items() #...[1]
sorted(d.items()) #...[2]

[1]ではタプル形式に変換します。[2]では、要素を昇順にソートします。

[('a', 10), ('b', 1), ('c', 22)]

なお、逆順(大きい順)にソートするにはsorted(d.items(), reverse=True)とします。

ここまでの内容で、あるテキストデータを読み込み、最も頻度の高い単語トップ10を作ることができます。これで、一通りのテキストの単語への分解とその単語をリスト化し、頻度を分析することができるようになりました。


4.Week 7

※この項はネタバレを含みます。

ネタバレ防止のため改行を入れ過ぎるのも見苦しいので、修了証を先にアップロードしておきますね。

画像1


さて、Week 7は・・・。


卒業式!!(笑)

そして知らない人がいるぞ!!(笑)

左の方は、Dr. Curt Bonk(インディアナ大学教授)だそうです。卒業?に際してのお言葉をいただきました。今後、大事にすべきことは次の'4P'および'4C'というもの。

4P: Passion, Purpose, Persistence, Playfulness
4C: Choice, Commitment, Connections, Completion

模擬卒業式を終え、第2コースも無事修了しました!他の試験勉強もあるので、少しゆっくり休んだら第3コースに進めていきます。

それでは、次のコースのエントリもお楽しみに!

この記事が気に入ったらサポートをしてみませんか?