数弱の文系大学生によるブログです。

Python、Webデザイン関連の記事を投稿していけたらなと思っています。

備忘録的なブログなので、読みにくい文章だと思います。ご了承ください。

Python3の復習(標準ライブラリ)

こんにちは。

上歯の裏側を火傷したかにたまごです。
口の中を火傷するとき、毎回上歯の裏側なんだよなぁ。すごく痛い。
火傷した部分を舌で濡らしながら書いていきます。


今回は

  • 標準ライブラリ

について、復習していきたいと思います。


今までのPython3 復習履歴は以下の通り。

  1. 数値・文字列
  2. リスト・タプル
  3. 辞書・集合
  4. if文・while文・for文
  5. 内包表記
  6. 関数
  7. ジェネレータ
  8. デコレータ
  9. 名前空間とスコープ
  10. アンダーバー・アンダースコアの意味
  11. エラー処理:try・except
  12. モジュール・パッケージ

標準ライブラリ

標準ライブラリとは、役立つモジュールが詰め込まれた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期生'}


やっぱり便利なものはどんどん使っていかないとね。
ライブラリ巡りでもしようかな。


以上です。