今さらPython3 (15) - 辞書

この本の第3章を読み進めてます。

入門 Python 3

入門 Python 3

辞書とは?

要素の順序が管理されていない代わりにキーを持っているのが特徴。勝手にハッシュキー的なイメージをしているけど、検索が早いのかどうかは個人的には未検証。

>>> empty_dict ={}
>>> empty_dict
{}
>>> bierce = {
...     "day": "A period of twenty-four hours, mostly misspent",
...     "positive": "Mistaken at the top of one's voice",
...     "misfortune": "The kind of fortune that never misses",
...     }
>>> bierce
{'positive': "Mistaken at the top of one's voice", 'day': 'A period of twenty-four hours, mostly misspent', 'misfortune': 'The kind of fortune that never misses'}

最後の要素の後ろのカンマは省略可、あと別にインデントしなくても良いらしい。

>>> lol = [['a','b'],['c','d'],['e','f']]
>>> lol
[['a', 'b'], ['c', 'd'], ['e', 'f']]
>>> dict(lol)
{'a': 'b', 'c': 'd', 'e': 'f'}
>>> lot = [('a','b'), ('c','d'), ('e','f')]
>>> dict(lot)
{'a': 'b', 'c': 'd', 'e': 'f'}
>>> tol=(['a','b'],['c','d'],['e','f'])
>>> dict(tol)
{'a': 'b', 'c': 'd', 'e': 'f'}
>>> los = ('ab','cd','ef')
>>> dict(los)
{'a': 'b', 'c': 'd', 'e': 'f'}
>>> tos = ['ab', 'cd', 'ef']
>>> dict(tos)
{'a': 'b', 'c': 'd', 'e': 'f'}
>>> dict(lol) == dict(lot) == dict(tol) == dict(los) == dict(tos)
True

2要素のシーケンスを含むのなら、何でも辞書に変換できると。今回は、たまたまキーの順番がアルファベット順になったけど、必ずしもそうならないことは経験済み。

もっと辞書っぽく

>>> pythons = {
... 'chapman': 'Graham',
... 'Cleese': 'John',
... 'Idle': 'Eric',
... 'Jones': 'Terry',
... 'Palin': 'Michael',
... }
>>> pythons
{'Idle': 'Eric', 'chapman': 'Graham', 'Jones': 'Terry', 'Palin': 'Michael', 'Cleese': 'John'}
>>> 

実はモンティ・パイソンよく知らないんだけど、辞書を作るのが主旨なので。さっき、インデントしなくても問題ないと言っていたので、インデントなしで作ってみました。

>>> pythons['Gilliam'] = 'Gerry'
>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Gerry', 'Idle': 'Eric', 'Palin': 'Michael', 'Cleese': 'John', 'Jones': 'Terry'}
>>>
>>> pythons['Gilliam'] = 'Terry'
>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Terry', 'Idle': 'Eric', 'Palin': 'Michael', 'Cleese': 'John', 'Jones': 'Terry'}
>>> 

辞書の中にないキーを指定すれば、新しいエントリが追加され、存在するキーがあれば値が上書きされる。

>>> for key in pythons:
...     print(key)
... 
chapman
Gilliam
Idle
Palin
Cleese
Jones
>>> some_pythons = {}
>>> for key in pythons:
...     some_pythons[pythons[key]] = key
... 
>>> some_pythons
{'Eric': 'Idle', 'Terry': 'Jones', 'John': 'Cleese', 'Graham': 'chapman', 'Michael': 'Palin'}
>>> 

この例は、ファーストネームとラストネームを入れ替えたパターンで、ファーストネームがTerryなのが2人いて、GilliamよりJones が後で処理されているから、some_pythonsの中ではJonesが残っていると理解できる。

辞書の統合

>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Terry', 'Idle': 'Eric', 'Palin': 'Michael', 'Cleese': 'John', 'Jones': 'Terry'}
>>> others = {'Marx':'Groucho', 'Howard':'Moe'}
>>> pythons.update(others)
>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Terry', 'Idle': 'Eric', 'Howard': 'Moe', 'Palin': 'Michael', 'Cleese': 'John', 'Marx': 'Groucho', 'Jones': 'Terry'}

update()を使って2つの辞書が統合できると。ただし、キーが重複していた場合は、第2の辞書の値が残る。

>>> first = {'a': 1, 'b': 2}
>>> second = {'b': 'platypus'}
>>> first.update(second)
>>> first
{'a': 1, 'b': 'platypus'}
<||

さっき、ファーストネームとラストネームを入れ替えたときの挙動を考えれば納得かな。

** 辞書から削除

削除の時は、del文でキーを指定する。

>|pythons|
>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Terry', 'Idle': 'Eric', 'Howard': 'Moe', 'Palin': 'Michael', 'Cleese': 'John', 'Marx': 'Groucho', 'Jones': 'Terry'}
>>> del pythons['Marx']
>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Terry', 'Idle': 'Eric', 'Howard': 'Moe', 'Palin': 'Michael', 'Cleese': 'John', 'Jones': 'Terry'}
>>> del pythons['Howard']
>>> pythons
{'chapman': 'Graham', 'Gilliam': 'Terry', 'Idle': 'Eric', 'Palin': 'Michael', 'Cleese': 'John', 'Jones': 'Terry'}
>>>

モンティ・パイソンと一緒にするからマルクス兄弟がお笑いコンビ名みたいに見えてきたw。さらにHowardも削除して、オリジナルメンバーに戻ったわけですね。

>>> pythons.remove('chapman')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'remove'

リストじゃないからpop()はないだろうと思ったけど、remove()はできるのかな?と思ったらダメでした。だから本にも載っていないのね。

(つづく)