Python3の復習(標準ライブラリ)
こんにちは。
上歯の裏側を火傷したかにたまごです。
口の中を火傷するとき、毎回上歯の裏側なんだよなぁ。すごく痛い。
火傷した部分を舌で濡らしながら書いていきます。
今回は
- 標準ライブラリ
について、復習していきたいと思います。
今までのPython3 復習履歴は以下の通り。
- 数値・文字列
- リスト・タプル
- 辞書・集合
- if文・while文・for文
- 内包表記
- 関数
- ジェネレータ
- デコレータ
- 名前空間とスコープ
- アンダーバー・アンダースコアの意味
- エラー処理:try・except
- モジュール・パッケージ
標準ライブラリ
標準ライブラリとは、役立つモジュールが詰め込まれたPythonの大規模なライブラリのこと。
公式ドキュメントで使いたいライブラリを見つけ、インポートするだけで使用できる。
- setdefault関数とdefaultdict関数
存在しない辞書のキーにアクセスしようとするとエラーが発生する。
dict = {"name":"Kanitamago", "language":"Python"} print(dict["age"])
Traceback (most recent call last): File "C:\Users\***\Desktop\Python\Test\blog_test.py", line 672, in <module> print(dict["age"]) KeyError: 'age'
辞書のget関数で、第二引数に存在しないキーにアクセスした場合のデフォルト値を設定することでエラーを避けられる。
none_text = "そのキーは存在しない" dict = {"name":"Kanitamago", "language":"Python"} keys = ["age", "name", "school", "language", "gender"] for key in keys: print("キー: ", key) print("バリュー: ", dict.get(key, none_text)) print() print(dict)
キー: age バリュー: そのキーは存在しない キー: name バリュー: Kanitamago キー: school バリュー: そのキーは存在しない キー: language バリュー: Python キー: gender バリュー: そのキーは存在しない {'name': 'Kanitamago', 'language': 'Python'}
setdefault関数もget関数と似ているが、存在しないキーにアクセスした場合、デフォルト値をそのキーの値とする点で異なる。
none_text = "そのキーは存在しない" dict = {"name":"Kanitamago", "language":"Python"} keys = ["age", "name", "school", "language", "gender"] for key in keys: print("キー: ", key) print("バリュー: ", dict.setdefault(key, none_text)) print() print(dict)
キー: age バリュー: そのキーは存在しない キー: name バリュー: Kanitamago キー: school バリュー: そのキーは存在しない キー: language バリュー: Python キー: gender バリュー: そのキーは存在しない {'name': 'Kanitamago', 'language': 'Python', 'age': 'そのキーは存在しない', 'school': 'そのキーは存在しない', 'gender': 'そのキーは存在しない'}
defaultdict関数は、引数に関数を渡しデフォルト値を設定する。
intを渡した場合。
from collections import defaultdict default_int = defaultdict(int) default_int["one"] = 1 num_list = ["one", "two", "three", "four"] for num in num_list: print(default_int[num]) print(default_int)
出力結果。
1 0 0 0 defaultdict(<class 'int'>, {'one': 1, 'two': 0, 'three': 0, 'four': 0})
strを渡した場合。
default_str = defaultdict(str) default_str["one"] = 1 num_list = ["one", "two", "three", "four"] for num in num_list: print(default_str[num]) print(default_str)
出力結果。
1 defaultdict(<class 'str'>, {'one': 1, 'two': '', 'three': '', 'four': ''})
boolを渡した場合。
default_bool = defaultdict(bool) default_bool["one"] = 1 num_list = ["one", "two", "three", "four"] for num in num_list: print(default_bool[num]) print(default_bool)
出力結果。
1 False False False defaultdict(<class 'bool'>, {'one': 1, 'two': False, 'three': False, 'four': False})
自分で定義した関数を渡すことも可能。
def not_exist_key(): return "(;^ω^)" default_myfunc = defaultdict(not_exist_key) default_myfunc["one"] = 1 num_list = ["one", "two", "three", "four"] for num in num_list: print(default_myfunc[num]) print(default_myfunc)
出力結果。
1 (;^ω^) (;^ω^) (;^ω^) defaultdict(<function not_exist_key at 0x0000027118982EA0>, {'one': 1, 'two': '(;^ω^)', 'three': '(;^ω^)', 'four': '(;^ω^)'})
- Counterで要素数を計算
Counterオブジェクトにリストを渡すことで、リスト内の要素数をカウントすることができる。
most_common関数を使うと、カウントされたすべての要素を降順に返してくれる。
from random import randint from collections import Counter list = [str(randint(1, 10))+"が出た数" for i in range(100)] my_counter = Counter(list) print(my_counter) print(my_counter.most_common()) for key, val in my_counter.most_common(): print("KEY: ", key) print("VALUE: ", val) print()
出力結果。
Counter({'4が出た数': 13, '10が出た数': 13, '9が出た数': 11, '5が出た数': 10, '8が出た数': 10, '3が出た数': 10, '7が出た数': 9, '2が出た数': 9, '6が出た数': 8, '1が出た数': 7}) [('4が出た数', 13), ('10が出た数', 13), ('9が出た数', 11), ('5が出た数', 10), ('8が出た数', 10), ('3が出た数', 10), ('7が出た数', 9), ('2が出た数', 9), ('6が出 た数', 8), ('1が出た数', 7)]
KEY: 4が出た数 VALUE: 13 KEY: 10が出た数 VALUE: 13 KEY: 9が出た数 VALUE: 11 KEY: 5が出た数 VALUE: 10 KEY: 8が出た数 VALUE: 10 KEY: 3が出た数 VALUE: 10 KEY: 7が出た数 VALUE: 9 KEY: 2が出た数 VALUE: 9 KEY: 6が出た数 VALUE: 8 KEY: 1が出た数 VALUE: 7
most_common関数の引数に整数を渡すと、上位からその整数分だけ返してくれる。
print(my_counter.most_common(2))
[('4が出た数', 13), ('10が出た数', 13)]
Counterオブジェクト同士の四則演算や集合を利用した要素の取得もできる。
list1 = [str(randint(1, 10))+"が出た数" for i in range(100)] list2 = [str(randint(1, 10))+"が出た数" for i in range(100)] my_counter1 = Counter(list1) my_counter2 = Counter(list2) print("COUNTER1: ", my_counter1) print("COUNTER2: ", my_counter2) my_counter3 = my_counter1 - my_counter2 print("COUNTER3: ", my_counter3) #和集合で同じ要素が被った場合、カウンタ値の多い方を取得する。 my_counter4 = my_counter1 | my_counter2 print("COUNTER4: ", my_counter4)
出力結果。
COUNTER1: Counter({'4が出た数': 13, '3が出た数': 11, '8が出た数': 11, '7が出た数': 11, '2が出た数': 10, '10が出た数': 10, '9が出た数': 9, '1が出た数': 9, '5が出た数': 8, '6が出た数': 8}) COUNTER2: Counter({'6が出た数': 13, '3が出た数': 12, '2が出た数': 12, '1が出た数': 11, '7が出た数': 11, '8が出た数': 10, '10が出た数': 9, '5が出た数': 8, '4が出た数': 8, '9が出た数': 6}) COUNTER3: Counter({'4が出た数': 5, '9が出た数': 3, '10が出た数': 1, '8が出た数': 1}) COUNTER4: Counter({'4が出た数': 13, '6が出た数': 13, '2が出た数': 12, '3が出た数': 12, '8が出た数': 11, '1が出た数': 11, '7が出た数': 11, '10が出た数': 10, '9が出た数': 9, '5が出た数': 8})
- OrderedDictによるキー順のソート
通常、辞書のキーの順序は予測不能のため、以下のような順で追加しても順序が異なる場合がある。
sample = {"cry":"( ノД`)", "smile":"(^○^)", "angry":"(# ゚Д゚)", "surprise": "(゚д゚)!"} for key in sample: print(key)
出力結果。
smile angry cry surprise
OrderedDictを使用すると、追加されたキーの順番を覚えさせることができる。
from collections import OrderedDict dict = OrderedDict({"cry":"( ノД`)", "smile":"(^○^)", "angry":"(# ゚Д゚)", "surprise": "(゚д゚)!"}) for key, val in dict.items(): print("KEY: ", key, " VALUE: ", val)
出力結果。
KEY: cry VALUE: ( ノД`) KEY: smile VALUE: (^○^) KEY: angry VALUE: (# ゚Д゚) KEY: surprise VALUE: (゚д゚)!
- デック:両端キュー
デックは、スタックとキューの両方の機能を持っている。
要は、シーケンスの両側から追加・削除をすることができる機能。
#左端、右端、どちらかからリストの要素を出力する def list_output(list, derection="left"): from collections import deque dq = deque(list) if derection == "right": for _ in range(len(dq)): print(dq.pop()) elif derection == "left": for _ in range(len(dq)): print(dq.popleft()) else: print("derection invalid value.")
derectionを指定しない場合。
list_output(["apple", "orange", "grape"])
出力結果。
apple orange grape
derection=right とする場合。
list_output(["apple", "orange", "grape"], derection="right")
出力結果。
grape orange apple
- intertoolsによるコード構造の反復処理
itertoolsには、効率的なループ実行のためのイテレータ生成関数が実装されている。
chain関数は、引数全体を一つのイテラブルとして扱えるようにする。
from random import randint two_dementional_array = [[i for i in range(1, randint(5, 10))] for _ in range(10)] for idx, array in enumerate(two_dementional_array): print(idx+1, ": ", array)
出力結果。
1 : [1, 2, 3, 4, 5] 2 : [1, 2, 3, 4] 3 : [1, 2, 3, 4, 5, 6, 7, 8, 9] 4 : [1, 2, 3, 4, 5] 5 : [1, 2, 3, 4, 5] 6 : [1, 2, 3, 4, 5, 6, 7, 8] 7 : [1, 2, 3, 4, 5, 6, 7, 8] 8 : [1, 2, 3, 4, 5, 6] 9 : [1, 2, 3, 4, 5, 6] 10 : [1, 2, 3, 4, 5, 6, 7, 8]
通常、二次元配列をfor文で回すと、上記のようにリストが出力される。
chain関数を使用した場合。
import itertools from random import randint two_dementional_array = [[i for i in range(1, randint(5, 10))] for _ in range(10)] for idx, array in enumerate(itertools.chain(*two_dementional_array)): print(idx+1, ": ", array)
出力結果。
1 : 1 2 : 2 3 : 3 4 : 4 5 : 5 6 : 1 7 : 2 8 : 3 9 : 4 10 : 1 11 : 2 12 : 3 13 : 4 14 : 5 15 : 6 16 : 7 17 : 8 18 : 9 19 : 1 20 : 2 21 : 3 22 : 4 23 : 5 24 : 1 25 : 2 26 : 3 27 : 4 28 : 5 29 : 1 30 : 2 31 : 3 32 : 4 33 : 5 34 : 6 35 : 7 36 : 8 37 : 1 38 : 2 39 : 3 40 : 4 41 : 5 42 : 6 43 : 7 44 : 8 45 : 1 46 : 2 47 : 3 48 : 4 49 : 5 50 : 6 51 : 1 52 : 2 53 : 3 54 : 4 55 : 5 56 : 6 57 : 1 58 : 2 59 : 3 60 : 4 61 : 5 62 : 6 63 : 7 64 : 8
cycle関数は、引数の要素を循環的に無限回返す。
lottery = ["当たり", "はずれ"] while True: output = "" try: for result in itertools.cycle(lottery): print(result) output = result except KeyboardInterrupt: print(output+"です") break
出力結果。
(無限に循環) 当たり はずれ 当たり はずれ (Ctrl + C キーで循環をストップ) 当たりです
accumulate関数は、渡されたリストの累積和を返す。
また、累積和の代わりに第二引数に関数を渡し、別の処理にすることも可能。
デフォルト。
for item in itertools.accumulate(["あいうえお", "かきくけこ", "さしすせそ", "たちつてと"]): print(item)
出力結果。
あいうえお あいうえおかきくけこ あいうえおかきくけこさしすせそ あいうえおかきくけこさしすせそたちつてと
関数を渡した場合。
def test(a, b): return a + "+" + b for item in itertools.accumulate(["あいうえお", "かきくけこ", "さしすせそ", "たちつてと"], test): print(item)
出力結果。
あいうえお あいうえお+かきくけこ あいうえお+かきくけこ+さしすせそ あいうえお+かきくけこ+さしすせそ+たちつてと
- pprintで綺麗な表示に
pprintは見栄えの悪い出力結果を綺麗に表示してくれる。
いつの日かの乃木坂辞書を使いまわす。
nogi = { "秋元真夏":"1期生", "生田絵梨花":"1期生", "井上小百合":"1期生", "衛藤美彩":"1期生", "齋藤飛鳥":"1期生", "斉藤優里":"1期生", "桜井玲香":"1期生", "白石麻衣":"1期生", "高山一実":"1期生", "中田花奈":"1期生", "西野七瀬":"1期生", "樋口日奈":"1期生", "星野みなみ":"1期生", "松村沙友里":"1期生", "和田まあや":"1期生", "伊藤純奈":"2期生", "北野日奈子":"2期生", "佐々木琴子":"2期生", "新内眞衣":"2期生", "鈴木絢音":"2期生", "寺田蘭世":"2期生", "堀未央奈":"2期生", "山崎怜奈":"2期生", "渡辺みり愛":"2期生" }
普通にprint関数で出力するとこうなる。コマンドプロンプトだとすごい見づらい。
print(nogi)
出力結果。
{'秋元真夏': '1期生', '生田絵梨花': '1期生', '井上小百合': '1期生', '衛藤美彩': '1期生', '齋藤飛鳥': '1期生', '斉藤優里': '1期生', '桜井玲香': '1期生', '白石麻衣': '1期生', '高山一実': '1期生', '中 田花奈': '1期生', '西野七瀬': '1期生', '樋口日奈': '1期生', '星野みなみ': '1期生', '松村沙友里': '1期生', '和田まあや': '1期生', '伊藤純奈': '2期生', '北野日奈子': '2期生', '佐々木琴子': '2期生', ' 新内眞衣': '2期生', '鈴木絢音': '2期生', '寺田蘭世': '2期生', '堀未央奈': '2期生', '山崎怜奈': '2期生', '渡辺みり愛': '2期生'}
pprint関数を使うと見やすくなる。
from pprint import pprint pprint(nogi)
出力結果。
{'中田花奈': '1期生', '井上小百合': '1期生', '伊藤純奈': '2期生', '佐々木琴子': '2期生', '北野日奈子': '2期生', '和田まあや': '1期生', '堀未央奈': '2期生', '寺田蘭世': '2期生', '山崎怜奈': '2期生', '斉藤優里': '1期生', '新内眞衣': '2期生', '星野みなみ': '1期生', '松村沙友里': '1期生', '桜井玲香': '1期生', '樋口日奈': '1期生', '渡辺みり愛': '2期生', '生田絵梨花': '1期生', '白石麻衣': '1期生', '秋元真夏': '1期生', '衛藤美彩': '1期生', '西野七瀬': '1期生', '鈴木絢音': '2期生', '高山一実': '1期生', '齋藤飛鳥': '1期生'}
やっぱり便利なものはどんどん使っていかないとね。
ライブラリ巡りでもしようかな。
以上です。