【Python連載】辞書内包表記で辞書を作成する


複数の値を1つにまとめて扱うことが出来るデータ形式の一つに、辞書と呼ばれるものがあります。
今回は辞書内包表記で辞書を作成する便利な方法を紹介します。


辞書内包表記で辞書を作成する

キーはキー、値は値、という形でそれぞれ別のリスト(もしくはタプル)で管理していたとします。
下記の二つのリストを紐づけて、辞書という形にしたくなった。そんな時にはどうしましょう。

keys = ["first_name","last_name","grade","class","Attendance","age"]  #キーのリスト
values = ["Yuki","Yoshino",3,"B",31,18]                               #値のリスト

手動で入力して辞書を定義してもよいのですが、それだと非常に手間が掛かります。上記例では、キーと値がそれぞれ6つ程度ですが、もっと数が増えたら大変ですよね。

そこで、辞書内包表記を使用することで、効率的に辞書にすることが可能です。

辞書内包表記は、次のような書式となります。

{キー:値 for 変数 in 配列名}

書式を見ても、いまいちピンと来ないかもしれませんね。
さっそく例を見てみましょう。

①キー(もしくは値)をリストから順次取り出す

ひとまず、キーだけをリストから取り出す例を見てみましょう。
リストから辞書のキーとなる要素を順次取り出し、今回は、値には全て”Python”という文字列を格納します。

keys = ["key0","key1","key2"]          #キーのリスト
dict = {key:"Python" for key in keys}  #keysから一つずつ要素を取り出し、辞書のキーとする。"Python"という文字列を値にする。
print(dict)
C:\Python> python 8-5-1.py
{‘key0’: ‘Python’, ‘key1’: ‘Python’, ‘key2’: ‘Python’}

このように、リストkeysに格納されていた各要素を、辞書のキーとすることが出来ました。

今回はkeysという一つのリストから取り出しただけですが・・・2つのリストからそれぞれ取り出すような場合には、少しテクニックが必要になります。

②キーと値の両方をリストから順次取り出す

今度は、キーだけではなく値もリストから取り出して、辞書にしていきます。
リストが2つあるという場合には、辞書内包表記で配列を指定する際に、それらをzip関数でまとめたzipオブジェクトというものに変えてあげる必要があります。
(zipオブジェクトとはざっくり言うと”要素の順次取り出しが可能なオブジェクトがまとまったオブジェクト”というようなイメージのものですが、詳細は割愛します)

keys = ["first_name","last_name","grade","class","Attendance","age"]  #キーのリスト
values = ["Yuki","Yoshino",3,"B",31,18]                               #値のリスト

dict = {key:value for key,value in zip(keys,values)}    #valuesリスト、keysリストを含むzipオブジェクトから各要素を順次取り出す
print(dict)
C:\Python> python 8-5-2.py
{‘first_name’: ‘Yuki’, ‘last_name’: ‘Yoshino’, ‘grade’: 3, ‘class’: ‘B’, ‘Attendance’: 31, ‘age’: 18}

リスト2つから辞書を作成することが出来ましたね。
上記例ではリストを用いていますが、タプルであっても同様のことが可能です。

ちなみにkeysリストとvaluesリストの要素数はそれぞれ同じく6つですが、要素数が異なっているという場合にはどうなるでしょうか。
keysリストの要素数を一つ減らしてみましょう。今回は、6つ目の要素”age”を削除してみます。

keys = ["first_name","last_name","grade","class","Attendance"]  #キーのリストの要素数は5
values = ["Yuki","Yoshino",3,"B",31,18]                         #値のリストの要素数は6

dict = {key:value for key,value in zip(keys,values)}
print(dict)
C:\Python> python 8-5-3.py
{‘first_name’: ‘Yuki’, ‘last_name’: ‘Yoshino’, ‘grade’: 3, ‘class’: ‘B’, ‘Attendance’: 31}

出力された辞書の要素数は6つではなく、5つとなりました。
このように、片方のリストから全ての要素の取り出しが終わると、もう片方のリストにはまだ要素が残っていても辞書に追加されることはありません。
※valuesリストの方の要素数を減らしても、同様のことが起きます。

〇おまけ

辞書内包表記では、if文も使用することが出来ます。
例として、keyに”class”という文字列の要素があった場合には、それは辞書に追加しないようにしてみます。

keys = ["first_name","last_name","grade","class","Attendance","age"]  #キーのリスト
values = ["Yuki","Yoshino",3,"B",31,18]                               #値のリスト

dict = {key:value for key,value in zip(keys,values) if key != "class"} #キーに"class"という文字列の要素があった場合には処理を行わない
print(dict)
C:\Python> python 8-5-4.py
{‘first_name’: ‘Yuki’, ‘last_name’: ‘Yoshino’, ‘grade’: 3, ‘Attendance’: 31, ‘age’: 18}

キー”class”:値”B”、という辞書の要素が含まれていないことわかります。
辞書の要素を削除するだけであれば後からdel文を使用する方法でも構わないのですが、
if文を使用して最初から省きたい要素を省いてしまうという方法もあるので、頭の片隅に入れておきましょう。

ちなみに、ここまで内包表記を使用してきましたが、別に内包表記を使用しなくてもリスト(タプル)から辞書を作成することは可能です。
次のコードを見てみましょう。

keys = ["first_name","last_name","grade","class","Attendance","Age"]  #キーのリスト
values = ["Yuki","Yoshino",3,"B",31,18]  #値のリスト

dict = {}                                #空の辞書の定義
for key,value in zip(keys,values):       #繰り返しのfor文
    if key == "class":                   #条件分岐のif~else文
        pass                             #何もしないという意味のpass
    else:
        dict[key] = value                #辞書にkeyとvalueを順次追加
print(dict)
C:\Python> python 8-5-5.py
{‘first_name’: ‘Yuki’, ‘last_name’: ‘Yoshino’, ‘grade’: 3, ‘Attendance’: 31, ‘Age’: 18}

辞書内包表記の場合と同じ結果が得られます。
ですが、辞書内包表記よりも、プログラムの行数が無駄に多いですよね。
内包表記では、プログラムをシンプルな記載にすることが出来ます。
※本記事のプログラム程度であれば実行速度に大した差はありませんが、処理の数が多い場合には、内包表記を使用した場合の方が処理速度が高速になるといわれています。

辞書内包表記を用いて辞書を作成する方法は、是非とも覚えておきましょう。


まとめ

リスト(タプル)から辞書を作成する際には、辞書内包表記を使用すると便利です。
キー、値のそれぞれを別のリスト(タプル)から取り出す際には、zipオブジェクトにする必要があります。


確認問題

次のような2つのリストがあります。

keys = ["key0","key1","key2"] 
values = [0,1,2] 

これらについて、以下の(1)(2)のプログラムを考えて、辞書を出力してみましょう。
(1)for文のみを使用した辞書内包表記で辞書を作成
(2)for文以外にもif文を使用して、keysリストの”Key2″を辞書の要素に含めないように辞書を作成

答えは次回の記事の最後に!
【Python連載】辞書型の、その他のメソッドの使い方


前回の確認問題の回答例

前回の記事はこちら→【Python連載】辞書のキー・値・要素を全て取り出す

次のようなプログラムがあります。

student_dict = {"first_name":"Ichiro",
                "last_name":"Suzuki",
                "grade":3}

print(student_dict.keys())
print(list(student_dict.values()))
print(student_dict.items())

5,6,7行目のprint()関数での出力はどのような形のものになるでしょうか。

・以下は解答になります。
・5行目のprint()関数の出力:dict_keys([‘first_name’, ‘last_name’, ‘grade’])
⇒キーについて、dict_keys型のオブジェクトが出力されます

・6行目のprint()関数の出力:[‘Ichiro’, ‘Suzuki’, 3] ⇒値について、リストが出力されます

・7行目のprint()関数の出力:dict_items([(‘first_name’, ‘Ichiro’), (‘last_name’, ‘Suzuki’), (‘grade’, 3)])
⇒キー・値について、dict_items型のオブジェクトが出力されます

  • このエントリーをはてなブックマークに追加

PAGE TOP