Python初級プログラミング(3)
2023/08/09
ハッシュタイプのデータ型があると助かる
  • ハッシュ/連想配列(Hash/Associative List)タイプのデータ型があるとプログラミングは楽になります。C++でもSTL(Standard Template Library)のmapコンテナを利用することで大分楽になりましたが、当然比較的新しい言語であるPythonもハッシュタイプのデータとして辞書(dictionary)(*1)を持っています。

  • もう一つ、Pythonにはタプル(tuple)と呼ばれるデータ型があります。immutable(不変)なリストです。今回はこのタプルと辞書を扱いたいと思います。

Python初級プログラミング(3):目次

タプルの作成: [目次へ]
  • 丸括弧で囲むとタプルになる(*2)。リストと同様にデータ種類の制約は無し。
  • immutableだがリストなのでインデックスを利用できる。データ変更しないリストのメソッドは使用できる。
  • tuple_a = (0,1,2,3,'A','B','C')
    
    print("tuple_a =",tuple_a)
    print("tuple_a[2] =",tuple_a[2])
    print("tuple_a[5] =",tuple_a[5])
    print("len =",len(tuple_a))
    
    >024_sample.py
    tuple_a = (0, 1, 2, 3, 'A', 'B', 'C')
    tuple_a[2] = 2
    tuple_a[5] = B
    len = 7
    

タプルは不変(immutable): [目次へ]
  • データ要素が数値/文字列リテラルの場合変更できない。タプル登録時にコピーしているだけなので。
  • データ要素がmutableオブジェクト(リファレンス)の場合間接的に変更できる。
  • 下記コードでtry/except使ってますが、エラー停止の回避です。
  • # 要素変更(1):タプルの要素は変更できない
    str_a = 'A'
    tuple_a = (0,1,2,3,str_a,'B','C')
    print("1: tuple_a =",tuple_a)
    
    try:
        print("1: pre tuple_a[0] =",tuple_a[0])
        tuple_a[0] = 10                          # ここで例外発生
        print("1: mod tuple_a[0] =",tuple_a[0])  # 実行されない
    except Exception as e0:
        print("1: >>発生した例外 =",e0)  # 例外の内容表示
    
    # 要素変更(2):数値/文字列変数(immutable)要素の変更は反映されない
    str_a = 'Z'
    print("2: tuple_a =",tuple_a)  # str_aの変更は反映されない
    
    # 要素変更(3):リスト(mutable)要素の変更は反映される
    list_a = [1,2,3,4]
    tuple_b = ('A','B','C',list_a)    # タプルの要素にリスト(mutable)を入れる
    print("3: pre tuple_b =",tuple_b) # 変更前の値表示
    
    list_a[1] = 200                   # list_a[1]の要素変更
    print("3: mod tuple_b =",tuple_b) # 変更の反映が確認できる
    
    >025_sample.py
    1: tuple_a = (0, 1, 2, 3, 'A', 'B', 'C')
    1: pre tuple_a[0] = 0
    1: >>発生した例外 = 'tuple' object does not support item assignment
    2: tuple_a = (0, 1, 2, 3, 'A', 'B', 'C')
    3: pre tuple_b = ('A', 'B', 'C', [1, 2, 3, 4])
    3: mod tuple_b = ('A', 'B', 'C', [1, 200, 3, 4])
    

タプルのアンパック(unpack): [目次へ]
  • タプルの要素を変数やリストに入れることができる。これらのアンパックはリストにも適用できる。
  • アンパックにワイルドカードを使用できる。複数データを受けた場合はリストになる。
  • tuple_a = ("Yamada", "170cm", "60kg")
    tuple_b = ("Sato", "180cm", "70kg")
    
    tuple_c = (tuple_a, tuple_b) # タプルを要素にしたタプル
    print("tuple_c = ", tuple_c)
    
    for t_idx in tuple_c:
        name, height, weight = t_idx # タプル要素のアンパック
        print("----------")
        print("name   =", name)
        print("height =", height)
        print("weight =", weight)
    
    print("----------")
    tuple_d = (0,1,2,3,4,5,6,7,8,9)
    v_head, *_ = tuple_d         # 先頭抽出
    print("v_head =", v_head)    # 先頭
    print("*_     =", _)         # 先頭以外(複数データはリストになる)
    
    print("----------")
    *_, v_tail = tuple_d         # 末尾抽出
    print("*_     =", _)         # 末尾以外(複数データはリストになる)
    print("v_tail =", v_tail)    # 末尾
    
    print("----------")
    v_head, *_, v_tail = tuple_d # 先頭と末尾抽出
    print("v_head =", v_head)    # 先頭
    print("*_     =", _)         # 先頭と末尾以外(複数データはリストになる)
    print("v_tail =", v_tail)    # 末尾
    
    >026_sample.py
    tuple_c =  (('Yamada', '170cm', '60kg'), ('Sato', '180cm', '70kg'))
    ----------
    name   = Yamada
    height = 170cm
    weight = 60kg
    ----------
    name   = Sato
    height = 180cm
    weight = 70kg
    ----------
    v_head = 0
    *_     = [1, 2, 3, 4, 5, 6, 7, 8, 9]
    ----------
    *_     = [0, 1, 2, 3, 4, 5, 6, 7, 8]
    v_tail = 9
    ----------
    v_head = 0
    *_     = [1, 2, 3, 4, 5, 6, 7, 8]
    v_tail = 9
    


辞書の作成と値呼び出し: [目次へ]
  • {キー: 値, キー: 値, ...} で作成する。辞書[キー値]で値を呼び出す。
  • 値呼び出しにはget()メソッドも使用できる。存在しないキーではNoneが戻る。
  • 空の辞書{}を作成して値追加するケースがほとんどかもしれない。
  • dict_a = {'a': 100, 'b': "二百", 'c': 300}
    print("dict_a =", dict_a)
    print("dict_a['b'] =", dict_a['b']) # キー値を指定して値呼び出し
    
    print("dicta_a.get('a') =", dict_a.get('a'))  # getで値取得
    print("dicta_a.get('d') =", dict_a.get('d'))  # 存在しないキー指定
    
    dict_b = {}
    print("dict_b =", dict_b)
    
    >027_sample.py
    dict_a = {'a': 100, 'b': '二百', 'c': 300}
    dict_a['b'] = 二百
    dicta_a.get('a') = 100
    dicta_a.get('d') = None
    dict_b = {}
    

辞書への値追加: [目次へ]
  • 辞書[キー値]=値で追加できる。
  • 辞書の多重化等も簡単にできる。リスト要素への追加はappend()や演算子が必要となるのは同じ。
    • Pythonでは宣言無しのオブジェクトは使えない(*3)ので、空辞書/リスト等の初期値設定は必要。
    dict_a = {} # 空の辞書
    
    dict_a['key_0'] = 'hoge' # key_0を追加
    print("1 : dict_a =", dict_a)
    
    dict_a['key_0'] = 100    # key_0を上書き
    print("2 : dict_a =", dict_a)
    
    dict_a['key_1'] = {}             # key_1に空辞書を追加
    dict_a['key_1']['key_a'] = '1_a' # key_1の指す辞書に値追加
    print("3a: dict_a =", dict_a)
    print("3a: dict_a['key_1']['key_a'] =", dict_a['key_1']['key_a'])
    
    dict_a['key_2'] = []          # key_2に空リストを追加
    dict_a['key_2'].append('2_a') # key_2の指すリストに値追加
    dict_a['key_2'].append('2_b') # key_2の指すリストに値追加
    print("4a: dict_a =", dict_a)
    print("4b: dict_a['key_2'][1] =", dict_a['key_2'][1])
    
    >028_sample.py
    1 : dict_a = {'key_0': 'hoge'}
    2 : dict_a = {'key_0': 100}
    3a: dict_a = {'key_0': 100, 'key_1': {'key_a': '1_a'}}
    3a: dict_a['key_1']['key_a'] = 1_a
    4a: dict_a = {'key_0': 100, 'key_1': {'key_a': '1_a'}, 'key_2': ['2_a', '2_b']}
    4b: dict_a['key_2'][1] = 2_b
    

辞書のメソッド:値削除:pop()/clear(): [目次へ]
  • 辞書.pop(キー値)で値を削除する。戻り値は削除した値。
  • 辞書.pop(キー値, デフォルト値)の場合、存在しないキー値指定時もデフォルト値を戻しエラーとしない。
  • clear()メソッドは全体削除
  • dict_a = {'a': 100, 'b': 200, 'c': 300}
    print("1 : dict_a =", dict_a)
    
    print("2a: remove b =", dict_a.pop('b'))  # キー'b'を削除
    print("2b: dict_a =", dict_a)
    
    dict_a.pop('d', None) 
    print("3a: remove d =", dict_a.pop('d', None))  # 存在しないキー'd'を削除
    print("3b: dict_a =", dict_a)
    
    dict_a.clear()  # 全体削除
    print("4 : dict_a =", dict_a)
    
    >029_sample.py
    1 : dict_a = {'a': 100, 'b': 200, 'c': 300}
    2a: remove b = 200
    2b: dict_a = {'a': 100, 'c': 300}
    3a: remove d = None
    3b: dict_a = {'a': 100, 'c': 300}
    4 : dict_a = {}
    

辞書のメソッド:イテラブル(iterable):keys()/values()/items(): [目次へ]
  • keys()メソッドはキーのリストを戻す。辞書自身をiterableにしてもキー値リストを戻す
  • values()メソッドは値のリストを戻す。
  • item()メソッドはキーと値のペアをタプルとしたリストを戻す。
  • dict_a = {'a': 100, 'b': 200}
    
    print("keys()   =", dict_a.keys())   # keys()メソッド
    print("values() =", dict_a.values()) # values()メソッド
    print("items()  =", dict_a.items())  # items()メソッド
    
    for o_idx1 in dict_a:
        print("1: iter =", o_idx1)
    
    for o_idx2 in dict_a.keys():
        print("2: iter =", o_idx2)
    
    for o_idx3 in dict_a.values():
        print("3: iter =", o_idx3)
    
    for o_idx4 in dict_a.items():
        print("4: iter =", o_idx4)
    
    >030_sample.py
    keys()   = dict_keys(['a', 'b'])
    values() = dict_values([100, 200])
    items()  = dict_items([('a', 100), ('b', 200)])
    1: iter = a
    1: iter = b
    2: iter = a
    2: iter = b
    3: iter = 100
    3: iter = 200
    4: iter = ('a', 100)
    4: iter = ('b', 200)


そして次回は
  • 次回ですが、標準入力/出力とファイル入力/出力を扱います。

  • 初級プログラミングで関数を扱わない理由についても触れる予定です。
Notes
  • 集合(Set)もありますが、初級プログラミングでは対象外とします。
  • 本当はカンマ(,)で区切ることがタプル作成の条件ですが、明示的なコーディングは大事です。
  • Perlだとできちゃうので「あれっ?」となることも。
Copyright(C) 2023 Altmo
本HPについて