Python学習【365日チャレンジ!】277日目のマスターU(@Udemy11)です。
ビリギャルの坪田先生の「才能の正体」をAudibleでずーっと聴いているのですが、読まなくても本が読めるという不思議な感覚を体験できるので、超お勧めですよ。
で、この本の中で紹介されている「ゲーム理論」のことを詳しく知りたくなって、図書館でゲーム理論に関する本をたくさん借りてきたのですが、ちょっと理解するのが難しくて頭がこんがらがっています。
期待値とかが関係してきたり、複雑な条件が入ってくると、若干思考停止状態に誘われてしまいます。
ただでさえ、酒井さんのPython講座も難しくなってきて、頭の中がオーバーヒート気味なので、すべてを忘れて海でのんびり餌釣りでもしたい気分です。
それでは今日も、Python学習を始めましょう。
昨日の復習
昨日は、int
だけでなくset
でも使えるdefaultdict
を学習しました。
集合は、リストなどに含まれる値の重複をまとめて同じ種類にまとめてくれましたが、defaultdict
を使って、辞書型データのkey
が同じでvalue
が違うものは、順番を保持してvalue
を追加したり、key
もvalue
も違うものは、key-value
を追加したりすることができました。
くわしくは昨日の記事をごらんください。
今日は、文字をカウントしていろいろ便利に活用できるcollections.Counter
を学習します。
Counter
Counter
は、defaultdict
と同じようにリストに含まれる値を集計することができます。
昨日のコードも活用して、Counter
で同じような出力をするコードを書いてみます。
import collections
d = {}
l = ['a', 'a', 'a', 'b', 'b', 'c']
for word in l:
if word not in d:
d[word] = 0
d[word] += 1
print(d)
d = {}
l = ['a', 'a', 'a', 'b', 'b', 'c']
for word in l:
d.setdefault(word, 0)
d[word] += 1
print(d)
d = collections.defaultdict(int)
l = ['a', 'a', 'a', 'b', 'b', 'c']
for word in l:
d[word] += 1
print(d)
c = collections.Counter()
l = ['a', 'a', 'a', 'b', 'b', 'c']
for word in l:
c[word] += 1
print(c)
print(c.most_common(2))
print(c.values())
print(sum(c.values()))
22行目までは昨日と同じコードで、24行目からのハイライトしている部分が追加したcollections.Counter
のコードです。
出力した結果は次のようになります。
出力結果
{'a': 3, 'b': 2, 'c': 1}
{'a': 3, 'b': 2, 'c': 1}
defaultdict(, {'a': 3, 'b': 2, 'c': 1})
Counter({'a': 3, 'b': 2, 'c': 1})
[('a', 3), ('b', 2)]
dict_values([3, 2, 1])
6
最初の3行は昨日のコードの出力で、for
ループとif
文を使ったものとsetdefault
を使ったものとdefaultdict
を使ったコードの出力です。
出力の4行目は、新しく追加したコード28行目print(c)
の出力で、Counter
オブジェクトとして、上記の3行と同じ値が保持されています。
コードの29行目は、most_common(2)
を使って保持している値のランキング上位2つを返して出力しています。
30行目は、values()
でCounter
オブジェクトに保持している辞書型データのvalue
だけを抽出して出力しています。
最後に、values()
で抽出した値をsum()
で合計して出力しています。
文字列を抽出
今回コードを記述したファイルはlesson5.py
という名前なので、このファイルを読み込んで、含まれる文字列を抽出してみます。
import re
with open('lesson5.py', 'r') as f:
words = re.findall(r'\w+', f.read().lower())
print(words)
print(collections.Counter(words).most_common(20))
出力結果
['import', 'collections', 'd', 'l', 'a', 'a', 'a', 'b', 'b', 'c', 'for', 'word', 'in', 'l', 'if', 'word', 'not', 'in', 'd', 'd', 'word', '0', 'd', 'word', '1', 'print', 'd', 'd', 'l', 'a', 'a', 'a', 'b', 'b', 'c', 'for', 'word', 'in', 'l', 'd', 'setdefault', 'word', '0', 'd', 'word', '1', 'print', 'd', 'd', 'collections', 'defaultdict', 'int', 'l', 'a', 'a', 'a', 'b', 'b', 'c', 'for', 'word', 'in', 'l', 'd', 'word', '1', 'print', 'd', 'c', 'collections', 'counter', 'l', 'a', 'a', 'a', 'b', 'b', 'c', 'for', 'word', 'in', 'l', 'c', 'word', '1', 'print', 'c', 'print', 'c', 'most_common', '2', 'print', 'c', 'values', 'print', 'sum', 'c', 'values', 'import', 're', 'with', 'open', 'main', 'py', 'r', 'as', 'f', 'words', 're', 'findall', 'r', 'w', 'f', 'read', 'lower', 'print', 'words', 'print', 'collections', 'counter', 'words', 'most_common', '20']
[('d', 12), ('a', 12), ('word', 11), ('c', 10), ('print', 9), ('l', 8), ('b', 8), ('in', 5), ('collections', 4), ('for', 4), ('1', 4), ('words', 3), ('import', 2), ('0', 2), ('counter', 2), ('most_common', 2), ('values', 2), ('re', 2), ('r', 2), ('f', 2)]
本来は先頭からライブラリをインポートしますが、便宜上、33行目でre
をインポートしています。
34行目でwith
ステートメントを使いlesson5.py
を開いてf
に代入し、35行目でre.findall
を使って、開いたファイル(lesson5.py
)を読み込んで小文字にしたデータの中から\w+
(最初の文字が任意の英数字で始まるパターン)で値を抽出してwords
に入れ、36行目で出力しています。
37行目は、先ほどやったCounter
とmost.common
を使って数の多い値順に20個を出力しています。
まとめ
collection.Counter
を使って値を抽出したり、加工したりして、いろいろな使い方ができました。
こんなことができるということがわかっても、なかなか具体的な使い方がイメージできません。
Pythonを学習するのは、Pythonを使って、何かを作り出すためなので、Python学習が目的になってしまっては本末転倒です。
とはいえ、Pythonの基礎基本を学習しないと実践では役に立ちません。
私の場合は、Python学習365日チャレンジを一つ目の目標にしているので、1年はしっかりとPythonの基礎基本を学習しようと思っていますが、ある程度Pythonの知識が身についてきたら、実践的なプログラムに取り組み出した方がPythonスキルが上がるような気がします。
気持ち的にはそろそろ具体的なプログラムに取りかかった方がいいのかな~なんて思うときがあるんですけどね。。。
それでは、明日もGood Python!