.. toctree:: ======================= 2. リスト変数と辞書変数 ======================= 第1回の講義で、1つの変数を定義して演算子を使って変数の内容を変更することを 行いました。関連のある変数や連続するデータを取り扱う場合、変数を一つの 塊として定義(リスト変数)したり、キーワードと結びつけて管理(辞書変数)し た方が効率的です。第2回は、データを塊として扱うためのリスト変数と辞書 変数の使い方を学びます。第2回講義の目的は以下のとおりです。 * リスト変数と辞書変数の定義の方法を覚える * リスト変数の要素の参照法(要素番号やスライス)を使えるようになる。 * 演算子を使ってリスト変数を演算する方法を理解する。 * 辞書変数のキーと要素を使えるようになる。 リスト変数 ========== 変数を連続して定義したり利用する場合は、1つの変数だけでなく **リスト** として変数を定義します。リスト変数が保持している変数を **要素** と呼び ます。n個の要素をもつ **リスト** は、データ(ベクトルの成分)が並んだn次元のベクト ルのようなものをイメージすると良いでしょう。 リスト変数の定義 ---------------- リスト変数の定義は、 **,** で要素を区切って並べて[ ]で囲み定義します。 .. code-block:: none list_variable = [variable0, variable1, variable2...] 要素番号は **0** から始まる整数になります。たとえば、5人分の体重を要素 としてもつリストを定義してみます。 .. code-block:: python :caption: example-01 :linenos: length = [74.5, 80.3, 120.2, 180.2, 220.3] # 5つ要素をもつリスト変数lengthを定義 この例では要素番号は0, 1, 2, 3, 4の5個です。5個の要素を定義した場合、最大の要素番号は4になります。 リスト変数の個別要素へのアクセス -------------------------------- リストの中の個別の要素は[ **要素番号(index)** ]でアクセスできます。 要素番号は0からはじまるint型です。リストの要素は、整数の要素番号を使って参照します。-1のような負値の要素番号は、リストのお尻から要素を参照すること になります。以下に例をあげています。 .. code-block:: python :caption: example-02 :linenos: length = [74.5, 80.3, 120.2, 180.2, 220.3] # 5つ要素をもつリストを定義 print(length) # lengthのすべての要素を表示 print(length[0]) # 74.5 print(length[1]) # 80.3 print(length[2]) # 120.2 print(length[3]) # 180.2 print(length[4]) # 220.3 print(length[-1]) # length[4]と同じ 220.3 print(length[-3]) # length[2]と同じ 120.2 print(length[5]) # これは定義されていないのでエラー lengthに以下のような並びでデータが保存されていることをイメージしてくだ さい。indexは0から始まることに注意です。5つの要素をもつリスト変数の場 合、indexは0, 1, 2, 3, 4なので、最大のindexは4になります。indexが5のデータは定義されていないのでエラーになります。 .. image:: list.png :align: center 1つのリストが保持する要素は、同じ型である必要はありません。たとえば、 以下の例では、int型とfloat型とstr型の要素をもったリストを定義していま す。 .. code-block:: python :caption: example-03 :linenos: a = [2, -1.0, "ohkubo"] # 3つのリストを定義 リスト変数のスライス処理 ------------------------ リスト変数から指定した要素をスライスして、新しいリストを作成することが できます。リスト変数のスライス操作は **:** を用いてスライスの始点と終 点を指定します。以下の例でスライス操作を理解しましょう。 .. code-block:: python :caption: example-04 :linenos: a = [2.0, -1, "hoge", 3, "a"] # 5つのリストを定義 b = a[0:3] # bは、index 0, 1, 2をスライスしたリストになる。b = [2.0, -1, "hoge"] b = a[ :3] # a[0:3]と同じスライス b = a[3:5] # bは、index 3, 4をスライスしたリストになる。b = [3, "a"] b = a[3: ] # a[3:5]と同じスライス b = a[-4: ] # a[1:]と同じスライス 要素の範囲を 1:4 と指定した場合、a[1], a[2], a[3]で構成するリストが生 成されます。a[4]は含まれないことに注意してください。スライスの始点と終 点を指定しない場合、0と最大の要素番号+1がセットされます。 リスト変数の変更 ---------------- 定義されたリストに対して、個別の要素の値を変更することができます。当然ですが、各要素で許されない演算(文字型*浮動小数等)があればエラーになります。 .. code-block:: python :caption: example-05 :linenos: a = [2.0, -1, "hoge", 3, "a"] # 5つのリストを定義 a[0] = 3 * 2 # a[0]の要素は6 a[2] = a[2] * 2 # a[2]の要素は"hogehoge" 定義されていないリストの要素にアクセスするとエラーになります。 .. code-block:: python :caption: example-06 :linenos: a = [2.0, -1, "hoge", 3, "a"] # 5つのリストを定義 a[5] = "b" # [5]は定義されていなのでエラー a[-6] = "b" # これもエラー リスト変数の演算 ---------------- リスト変数に許される演算は、 **リスト演算同士** の **+** と整数との **\*** のみです。 .. list-table:: :header-rows: 1 :widths: 10, 40, 80 * - 演算子 - 演算例 - 演算結果 * - \+ - [3, 2, 5] + [\"hoge\", \"huga\", 3] - [3, 2, 5, \"hoge\", \"huga\", 3] * - \* - 3 * [\"hoge\", \"huga\"] - [\"hoge\", \"huga\", \"hoge\", \"huga\", \"hoge\", \"huga\"] example-07はリスト変数とリスト変数の足し算の例です。リスト変数とリスト変数を **+** で演算することで、リスト変数にが結合したリストが生成されます。この演算によってリストに要素を追加することができます。 .. code-block:: python :caption: example-07 :linenos: a = [0, 2, 3, 4] # リストaの定義 b = ["hoge", 3.0, 89, 3] # リストbの定義 c = a + b # aとbが結合した c = [0, 2, 3, 4,"hoge", 3.0, 89, 3]が生成 print(c) # 定義されたリストに1つの要素を追加したい場合 c = a + [3] # 要素3をaに追加 c =[0, 2, 3, 4, 3] a += [3] # 単項演算子でaに要素3を追加(わかりにくいのでおすすめしない) print(a, c) # [0, 2, 3, 4, 3] [0, 2, 3, 4, 3]の出力 example-08はリスト変数とint型との掛け算の例です。整数nをリストに掛けた場合、1つのリストがn回繰り替えした要素をもつリストが生成されます。 .. code-block:: python :caption: example-08 :linenos: a = [0, 2, 3, 4] # リストの定義 a = 2 * a # aは[0, 2, 3, 4, 0, 2, 3, 4, ] b = [0] # 1つの要素をもつリストの定義 b *= 5 # 単項演算子をつかってa=[0, 0, 0, 0, 0]にupdate print(a, b) # [0, 2, 3, 4, 0, 2, 3, 4] [0, 0, 0, 0, 0]の出力 文字型とリスト -------------- str型変数を定義した場合、1文字1文字が要素となるリスト変数として定義されます。以下の例をみてください。 .. code-block:: python :caption: example-09 :linenos: chiba = "chiba uni." # str型のchibaを定義。スペースも1文字なことに注意 print(chiba[0]) # chibaのindex0は"c" print(chiba[1]) # chibaのindex1は"h" print(chiba[2]) # chibaのindex2は"i" print(chiba[3]) # chibaのindex3は"b" print(chiba[3:6]) # chibaのindex3は"ba " リストとして文字のデータは次のように配列さています。 .. image:: list_str.png :align: center str型変数の演算は、str方同士の足し算( + )とint型と掛け算( **\*** )だけ許されます。 str型はリストでもあるので、リスト変数に許される演算と同じルールです。 .. code-block:: python :caption: example-10 :linenos: chiba = "chiba uni." # str型のchibaを定義。スペースも1文字なことに注意 s = chiba + " faculty of eng." # " faculty of eng."を追加し"chiba uni. faculty of eng."を生成 t = chiba[:6] + "uniersity" # "chiba "に"university"を追加し"chiba university""を生成 print(s) # sの出力 print(t) # tの出力 u = 3 * chiba[0:3] + "-ba" + chiba[-5:] # "chichichi-ba uni."を生成 print(u) 多次元リスト ------------ リストの中の要素をリストとすることで、多次元リストを定義することができま す。以下のは、3×3の2次元配列を定義した例です。3行3列の行列を思い浮か べてください。 .. code-block:: python :caption: example-11 :linenos: two_dim = [[3, 4, 5], [9, 19, 12], [0, 3, 4]] print(two_dim[0][0]) # 1行1列の要素9にアクセス print(two_dim[1][2]) # 2行3列の要素12にアクセス print(two_dim[2][2]) # 3行3列の要素4にアクセス 以下のようなデータの並びをイメージしてください。 .. image:: list_mat.png :align: center 文字列を要素としたむリストを定義した場合、indexで要素を取り出してから、特定の文字にアクセスできます。 .. code-block:: python :caption: example-12 :linenos: chiba = ["ohkubo", "chem", "kyosei", "工学部"] # 文字列の定義 print(chiba[0]) # ohkubo print(chiba[1][2]) # e print(chiba[1][0:2]) # ch print(chiba[-1][-2]) # 学 以下のようなデータの並びになります。 .. image:: list_str2d.png :align: center 多次元リストで、各要素のリストは同じ要素数である必要がありません。また複数行にわたって定義することも許されます。 .. code-block:: python :caption: example-13 :linenos: l = [["1", "2", "3"], ["原子番号"], ["主量子数", "方位量子数", "磁気量子数", "スピン量子数"], ["シュレディンガー", "方程式"]] s = l[1][0] + l[0][1] + "の" + l[2][0] + "は" + l[0][0] print(s) # "原子番号2の主量子数は1"の出力 整数とリストの足し算は許されないので以下の例はエラーになることに注意です。 .. code-block:: python :caption: example-14 :linenos: l = [["1", "2", "3"], ["原子番号"], ["主量子数", "方位量子数", "磁気量子数", "スピン量子数"], ["シュレディンガー", "方程式"]] l[0] = [1, 2, 3] # l[0]の要素を[1, 2, 3]に変更 s = l[1][0] + l[0][1] + "の" + l[2][0] + "は" + l[0][0] # l[0][1]とl[0][0]は整数なのでエラー .. note:: pythonの基本機能で提供されているリストの操作や演算は、科学技術計算で頻出する行列計算を効率的(高速)に行うことができません。科学技術計算で多用する多次元配列の操作や演算は、後述するnumpyを使って行います。 .. 講義後に追加 ============ 大窪がメモしたファイルを置いておきます。参考にしてください。 :download:`第3回講義メモ <2018-10-17/第3回講義メモ.pdf>` .. アンケートの統計 ---------------- .. image:: 2018-10-17/statistics.png :width: 800px :align: center 辞書変数 ======== リスト変数は0から始めるindexで要素に結びつけられていました。 indexの代わりにkeyで要素を管理するのが辞書型です。リストと似てますが、 keyで要素が結びつけているのが辞書型の特徴です。リストで1つのindex番号 が複数の要素を持たないように辞書型も1つのkeyは1つの要素を持ちます。 辞書の定義 ---------- 辞書変数の定義は以下のように行います。keyの型はint, floatまたは文字型 の何でも良いです。要素としてリストを持つことも可能です。 .. code-block:: none dic = {key1: value1, key2, value2, ...} 具体的な、辞書変数を定義する例は以下のとおりです。 .. code-block:: python :caption: example-15 dic = {"hoge": 0, 3: 4} # "hoge"が要素0のkey, 3が要素4のkey dicの値にアクセスしたり値を変更したりしてみます。 .. code-block:: python :caption: example-16 dic = {"hoge": 0, 3: 4} # key="hoge"が0のkey, 3が4のkey print(dic["hoge"]) # "key=hoge"の要素0を表示 dic[3] = "hoge" # key=3の要素を"hoge"に変更 print(dic[3]) # key=3の要素"hoge"を表示 リスト変数は、異なる点は新しいkeyを指定することで要素を追加できることです。 .. code-block:: python :caption: example-17 :linenos: dic = {"hoge": 0, 3: 4} # "hoge"が0のkey, 3が4のkey dic["huga"] = 32 # key="huga"の要素32が追加された。 dic["千葉大"] = "稲毛区" # key="千葉大"の要素"稲毛区"が追加された。 print(dic) # 辞書変数の表示 辞書変数は要素としてリストをもつこともできます。 .. code-block:: python :caption: example-18 :linenos: dic = {"大学": ["千葉", "茨城", "東京", "Oxford"], "小学校": ["緑", "千葉大付属", "登戸"]} # 辞書の定義 print(dic["大学"][0]) # "千葉" print(dic["小学校"][1:3]) # ["千葉大付属", "登戸"] .. note:: リスト変数と異なり、スライス操作による要素の削除や演算による要素の追加は、許されていません。 クイズ ====== Q1 -- 以下のリストを変更し、 [\"chiba\", 3, 4, 8]のリストにし表示する。 .. code-block:: python hoge = [0, 1, 2, "chiba"] 答え .. code-block:: python :linenos: hoge = [0, 1, 2, "chiba"] hoge[0] = "chiba" hoge[1] = 3 hoge[2] = 4 hoge[3] = 8 print(hoge) Q2 -- 以下のリスト変数を操作して要素10を取り出す。また、スライス操作を行って[\"chiba\", 5, 7, 9]を要素にもつ新しいリスト変数hugaを作り表示する。 .. code-block:: python hoge = [0, 1, 2, "chiba", 5, 7, 9, 10, 12] 答え .. code-block:: python :linenos: hoge = [0, 1, 2, "chiba", 5, 7, 9, 10, 12] l = hoge[3:7] print(l) Q3 -- 以下のリストaとbを演算して[1, 2, 3, 1, 2, 3, 4, 5, 6]を要素にもつリストcを作り表示する。 .. code-block:: python :linenos: a = [1, 2, 3] b = [4, 5, 6] 答え .. code-block:: python :linenos: a = [1, 2, 3] b = [4, 5, 6] l = a + a + b print(l) Q4 -- 以下の文字変数から文字列"共生"を取り出して表示する。 .. code-block:: python s = "私は千葉大学工学部共生応用化学科です。" 答え s = "私は千葉大学工学部共生応用化学科です。" print(s[9:11]) Q5 -- 以下の文字変数を操作して文字列 \"私は千葉大生。\" を取り出して表示する。 .. code-block:: python s = "私は千葉大学工学部共生応用化学科です。" 答え .. code-block:: python :linenos: s = "私は千葉大学工学部共生応用化学科です。" l = s[2:5] + s[-9] + s[-3:] print(l) Q6 -- 以下のリスト変数から文字列 \"県の人口は6,268,585人\" を取り出して表示する。 .. code-block:: python chiba = ["千葉県は、日本の関東地方南東側に位置する", "広域地方公共団体のひとつ", "県庁所在地及び最大の都市は千葉市", "県の人口は6,268,585人", "面積は5,157.61平方キロメートルである"] 答え .. code-block:: python :linenos: s = "私は千葉大学工学部共生応用化学科です。" l = s[2:5] + s[-9] + s[-3:] print(l) Q7 -- 以下の2次元リストから文字\"uni\"を取り出して表示する。 .. code-block:: python :linenos: s = [["hoge", 3, 4], ["chiba university", "千葉"]] 答え .. code-block:: python :linenos: s = [["hoge", 3, 4], ["chiba university", "千葉"]] print(s[1][0][6:9]) Q8 -- 文字列 A = "hogehoge" を演算(1文で)して文字列"hoghoghog"を作って表示する。 .. code-block:: python :linenos: A = "hogehoge" 答え .. code-block:: python A = "hogehoge" print(3 * A[0:3]) Q9 -- スライス操作を行ってリストAとBそれぞれから[3, 4]を抜き出して表示する。 .. code-block:: python :linenos: A = [9, 3, 20, 3, 4] B = [[2, 3, 4], ["hoge", 3, 8], [0, 1]] 答え .. code-block:: python A = [9, 3, 20, 3, 4] B = [[2, 3, 4], ["hoge", 3, 8], [0, 1]] print("A", A[-2:]) print("B", B[0][1:]) Q10 --- 空のリストを3つもつ2次元リストと1次元リストa, b, cを次のように定義する。 .. code-block:: python list_2d = [[], [], []] a = [3, 4, 5] b = [1, 2] c = [8, 9, 10] 定義した空リストへ演算操作をして次のリストを作成し表示する。 .. code-block:: python [[3, 4, 5], [1, 2], [8, 9, 10]] 答え .. code-block:: python list_2d = [[], [], []] a = [3, 4, 5] b = [1, 2] c = [8, 9, 10] list_2d[0] = a list_2d[1] = b list_2d[2] = c print(list_2d) Q11 --- 以下の辞書型変数から100を取り出して表示する。 .. code-block:: python dic = {80: 3, 4: "hoge", "千葉大": 100, 3: "千葉大"} 答え .. code-block:: python :linenos: dic = {80: 3, 4: "hoge", "千葉大": 100, 3: "千葉大"} s = dic["千葉大"] print(s) Q12 --- 以下の辞書型変数からkeyが\"千葉大\"の要素を表示する。さらに、keyが\" 共生\"で要素が2のデータを辞書変数dicに追加する。 .. code-block:: python dic = {80: 3, 4: "hoge", "千葉大": 100, 3: "千葉大"} 答え .. code-block:: python :linenos: dic = {80: 3, 4: "hoge", "千葉大": 100, 3: "千葉大"} s = dic["千葉大"] dic["共生"] = 2 print(dic) Q13 --- 空の辞書変数(element = {})を定義し、以下のkeyと要素からなる辞書変数デー タを作成する。作成したelementにアクセスしてGaの原子量を表示させる。 .. csv-table:: :header-rows: 1 :widths: 6, 10 "key", "要素" "B", "10.811" "Al", "26.981539" "Ga", "69.723" "In", "114.818" "Tl", "204.3833" 答え .. literalinclude:: kadai-1.py Q14 --- 次のように辞書変数dic[a]とdic[b]を定義する。 .. code-block:: python a, b = 1, 2 dic = {} dic[a] = [[4, 5], ["a", "b", "c"], [10, 11]] dic[b] = [['x', 'y', 'z'], [3, 4, 5]] 定義した辞書変数の参照し、リストのスライス処理と演算で次の内容を表示する。 .. code-block:: python [3, 4, 5, 'x', 'y', 'z'] .. .. 答え .. code-block:: python a, b = 1, 2 dic = {} dic[a] = [[3, 4, 5], ["a", "b", "c"], [10, 11]] dic[b] = [['x', 'y', 'z'], [3, 4, 5]] print(dic[1][0] + dic[2][0])