東京大学のPythonプログラミング入門「3-1. 辞書 (dictionary)」備忘録

Python勉強中で備忘録です。

⇒以下の解答を考えたが、間違い。ChatGPTで添削。
・for の使い方について、間違えていたのは理解。しかし、正しい解答については示されても理解できない。「enumerate」なんて習っていない(気がする)。「for i, value in enumerate(list1)」を見ても、特に納得しない。
・角括弧 []は単純なミス。OK。
・私は要素をlist1[x](list1のx番目の要素)で表現して、インデックスをxで表現したつもりであるので、「キーと値の逆転の理解」はしていない。

def reverse_lookup(list1):
dict1 = {}
for x in list1:
dict1{list1[x]}= x
return dict1

問題点

  1. for の使い方
    • for x in list1: とすると、xリストの要素そのもの になります。
    • でもここで欲しいのは「インデックス」なので、そのままでは意図通りになりません。
    ✅ 解決策: for i, value in enumerate(list1): とすればインデックスと要素が同時に取れる。

  1. 辞書の代入方法の誤り
    • dict1{list1[x]} = x は文法エラーです。
    • Python で辞書に代入する場合は、角括弧 [] を使います。
      つまり dict1[key] = value という形。
    ✅ 例えば dict1[value] = i のように書く。

  1. キーと値の逆転の理解
    • 問題文では「要素 value をキー、インデックスを値」にしたい。
    • あなたのコードはその意図を満たせていません(インデックスと要素の扱いが逆になっている)。

修正版コード

def reverse_lookup(list1):
    dict1 = {}
    for i, value in enumerate(list1):
        dict1[value] = i
    return dict1

✅ まとめると、あなたのコードの問題点は

  1. for x in list1: ではインデックスを取れない
  2. 辞書代入に {} を使っていて文法エラー
  3. インデックスと値の対応が逆になっている

<模範解答>

def reverse_lookup(list1):
    dic1 = {}  # 空の辞書を作成する
    for value in list1:
        dic1[value] = list1.index(value)
    return dic1
#reverse_lookup(['apple', 'pen', 'orange'])

⇒以下の解答①を考え、それならifでもelseでも一緒だと考え、②に修正したが、間違い。②についてChatGPTで添削。appendとextendの違いを理解していなかった。値の追加と入れ替えを勘違いした。リストの特定のキーの値に要素を追加するのは直接的にはテキストに記載がないのでは。模範解答は「リストの特定のキーの値に要素を追加する」ことをしていないので、習った範囲で回答している。

解答①
def handle_collision(dic1, str1):
n = len(str1)
ls = []
ls.extend(str1)
if n not in dic1:
dic1[n] = ls
else:
dic1[n] = ls

解答②
def handle_collision(dic1, str1):
n = len(str1)
ls = []
ls.extend(str1)
dic1[n] = ls

問題点

  1. ls.extend(str1) の誤用
    • extend は「イテラブルを展開してリストに追加する」メソッドです。
    • そのため ls.extend(str1) とすると、"abc"["a", "b", "c"] のように文字ごとに分解されてしまいます。
    • 問題文が求めているのは 文字列全体を 1 要素として扱う ことなので、append(str1) を使う必要があります。
    ✅ 修正: ls.append(str1)

  1. 既にキーがある場合を考慮していない
    • 問題文では「キーが存在しない場合は新しいリストを作る」「存在する場合は既存のリストに追加する」となっています。
    • あなたのコードは常に dic1[n] = ls上書き してしまいます。
    • これだと、既にキーが存在しても過去のデータが消えてしまいます。
    ✅ 修正: if n in dic1: dic1[n].append(str1) else: dic1[n] = [str1]

正しいコード例

def handle_collision(dic1, str1):
    n = len(str1)
    if n in dic1:
        dic1[n].append(str1)   # 既存のリストに追加
    else:
        dic1[n] = [str1]       # 新しいリストを作成して登録

<模範解答>

def handle_collision(dic1, str1):
    if dic1.get(len(str1)) is None:
        ls = [str1]
    else:
        ls = dic1[len(str1)]
        ls.append(str1)
    dic1[len(str1)] = ls
#handle_collision({3: ['ham', 'egg'], 6: ['coffee', 'brandy'], 9: ['port wine'], 15: ['curried chicken']}, 'tea')

<今回の理解内容>
・辞書は、キー (key) と値 (value) を対応づける。値からキーを取り出すことはできない。リストのようにインデックスを指定して値を取得できない。
・リストの特定のキーの値に直接要素を追加できる。*テキストには記載なし。
・appendはそのまま、それを追加する。要素なら要素(catならcat)、リストならリストのまま追加する。
・extendは1つ階層を下げて追加。要素なら文字列、リストなら中の要素を追加する。

コメント

タイトルとURLをコピーしました