Pythonの辞書

Pythonの辞書

Pythonは、dictionaryと呼ばれる別の複合data typeを提供します。これは、オブジェクトのコレクションであるという点でリストに似ています。

Here’s what you’ll learn in this tutorial: Python辞書の基本的な特徴を説明し、辞書データにアクセスして管理する方法を学びます。 このチュートリアルを終了したら、いつ辞書が使用するのに適切なデータ型であるか、そしてその方法を十分に理解する必要があります。

辞書とリストには、次の特徴があります。

  • どちらも変更可能です。

  • 両方とも動的です。 必要に応じて拡大および縮小できます。

  • 両方をネストできます。 リストには別のリストを含めることができます。 辞書には別の辞書を含めることができます。 辞書にはリストも含めることができ、その逆も可能です。

辞書は、主に要素へのアクセス方法がリストと異なります。

  • リスト要素は、インデックスを介して、リスト内の位置によってアクセスされます。

  • 辞書要素にはキーを介してアクセスします。

__ Take the Quiz:インタラクティブな「PythonDictionaries」クイズで知識をテストします。 完了すると、学習の進捗状況を経時的に追跡できるようにスコアを受け取ります。

辞書を定義する

辞書は、一般的に連想配列として知られるデータ構造のPythonの実装です。 辞書は、キーと値のペアのコレクションで構成されます。 各キーと値のペアは、キーをその関連する値にマッピングします。

キーと値のペアのコンマ区切りリストを中括弧({})で囲むことにより、辞書を定義できます。 コロン(:)は、各キーを関連する値から区切ります。

d = {
    : ,
    : ,
      .
      .
      .
    : 
}

次は、場所を対応するメジャーリーグベースボールチームの名前にマップする辞書を定義しています。

>>>

>>> MLB_team = {
...     'Colorado' : 'Rockies',
...     'Boston'   : 'Red Sox',
...     'Minnesota': 'Twins',
...     'Milwaukee': 'Brewers',
...     'Seattle'  : 'Mariners'
... }

組み込みのdict()関数を使用して辞書を作成することもできます。 dict()の引数は、キーと値のペアのシーケンスである必要があります。 タプルのリストはこれに適しています:

d = dict([
    (, ),
    (, , )
])

MLB_teamは、次のように定義することもできます。

>>>

>>> MLB_team = dict([
...     ('Colorado', 'Rockies'),
...     ('Boston', 'Red Sox'),
...     ('Minnesota', 'Twins'),
...     ('Milwaukee', 'Brewers'),
...     ('Seattle', 'Mariners')
... ])

キー値が単純な文字列である場合、キーワード引数として指定できます。 したがって、MLB_teamを定義するさらに別の方法があります。

>>>

>>> MLB_team = dict(
...     Colorado='Rockies',
...     Boston='Red Sox',
...     Minnesota='Twins',
...     Milwaukee='Brewers',
...     Seattle='Mariners'
... )

辞書を定義すると、リストでできるのと同じように、その内容を表示できます。 上記の3つの定義はすべて、表示されると次のように表示されます。

>>>

>>> type(MLB_team)


>>> MLB_team
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Twins',
'Milwaukee': 'Brewers', 'Seattle': 'Mariners'}

辞書のエントリは、定義された順序で表示されます。 しかし、それらを取得することになると、それは無関係です。 ディクショナリ要素は、数値インデックスによってアクセスされません。

>>>

>>> MLB_team[1]
Traceback (most recent call last):
  File "", line 1, in 
    MLB_team[1]
KeyError: 1

辞書値へのアクセス

もちろん、辞書の要素には何らかの方法でアクセスできる必要があります。 インデックスで取得しない場合、どのように取得しますか?

値は、対応するキーを角括弧([])で指定することにより、辞書から取得されます。

>>>

>>> MLB_team['Minnesota']
'Twins'
>>> MLB_team['Colorado']
'Rockies'

辞書にないキーを参照すると、Pythonは例外を発生させます。

>>>

>>> MLB_team['Toronto']
Traceback (most recent call last):
  File "", line 1, in 
    MLB_team['Toronto']
KeyError: 'Toronto'

既存の辞書へのエントリの追加は、単に新しいキーと値を割り当てるだけです。

>>>

>>> MLB_team['Kansas City'] = 'Royals'
>>> MLB_team
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Twins',
'Milwaukee': 'Brewers', 'Seattle': 'Mariners', 'Kansas City': 'Royals'}

エントリを更新する場合、既存のキーに新しい値を割り当てることができます。

>>>

>>> MLB_team['Seattle'] = 'Seahawks'
>>> MLB_team
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Twins',
'Milwaukee': 'Brewers', 'Seattle': 'Seahawks', 'Kansas City': 'Royals'}

エントリを削除するには、delステートメントを使用して、削除するキーを指定します。

>>>

>>> del MLB_team['Seattle']
>>> MLB_team
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Twins',
'Milwaukee': 'Brewers', 'Kansas City': 'Royals'}

過ぎ去った、シーホークス! あなたはNFLチームです。

辞書キーと リストインデックス

未定義のキーまたは数値インデックスのいずれかを使用して辞書にアクセスすると、インタープリターが同じ例外KeyErrorを発生させることに気付いたかもしれません。

>>>

>>> MLB_team['Toronto']
Traceback (most recent call last):
  File "", line 1, in 
    MLB_team['Toronto']
KeyError: 'Toronto'

>>> MLB_team[1]
Traceback (most recent call last):
  File "", line 1, in 
    MLB_team[1]
KeyError: 1

実際、同じエラーです。 後者の場合、[1]は数値インデックスのように見えますが、そうではありません。

このチュートリアルの後半で、不変型のオブジェクトを辞書キーとして使用できることを確認します。 したがって、整数を使用できない理由はありません。

>>>

>>> d = {0: 'a', 1: 'b', 2: 'c', 3: 'd'}
>>> d
{0: 'a', 1: 'b', 2: 'c', 3: 'd'}

>>> d[0]
'a'
>>> d[2]
'c'

MLB_team[1]d[0]、およびd[2]では、角括弧内の数値はインデックスのように表示されます。 ただし、辞書内のアイテムの順序とは関係ありません。 Pythonはそれらを辞書キーとして解釈しています。 この同じ辞書を逆の順序で定義しても、同じキーを使用して同じ値を取得できます。

>>>

>>> d = {3: 'd', 2: 'c', 1: 'b', 0: 'a'}
>>> d
{3: 'd', 2: 'c', 1: 'b', 0: 'a'}

>>> d[0]
'a'
>>> d[2]
'c'

構文は似ているかもしれませんが、辞書をリストのように扱うことはできません。

>>>

>>> type(d)


>>> d[-1]
Traceback (most recent call last):
  File "", line 1, in 
    d[-1]
KeyError: -1

>>> d[0:2]
Traceback (most recent call last):
  File "", line 1, in 
    d[0:2]
TypeError: unhashable type: 'slice'

>>> d.append('e')
Traceback (most recent call last):
  File "", line 1, in 
    d.append('e')
AttributeError: 'dict' object has no attribute 'append'

Note:ディクショナリ内のアイテムへのアクセスは順序に依存しませんが、Pythonはディクショナリ内のアイテムの順序が保持されることを保証します。 表示されると、項目は定義された順序で表示され、キーの繰り返しもその順序で発生します。 辞書に追加されたアイテムは最後に追加されます。 アイテムが削除された場合、残りのアイテムの順序は保持されます。

あなたはごく最近になってこの順序の保存に頼ることができます。 added as a part of the Python language specification in version 3.7でした。 ただし、バージョン3.6の時点でも同様でした。実装の結果として偶然に発生したものですが、言語仕様では保証されていません。

辞書をインクリメンタルに作成する

上記のように、中括弧とキーと値のペアのリストを使用して辞書を定義することは、すべてのキーと値を事前に知っている場合は問題ありません。 しかし、その場で辞書を作成したい場合はどうでしょうか?

まず、空の中括弧で指定された空の辞書を作成します。 その後、新しいキーと値を1つずつ追加できます。

>>>

>>> person = {}
>>> type(person)


>>> person['fname'] = 'Joe'
>>> person['lname'] = 'Fonebone'
>>> person['age'] = 51
>>> person['spouse'] = 'Edna'
>>> person['children'] = ['Ralph', 'Betty', 'Joey']
>>> person['pets'] = {'dog': 'Fido', 'cat': 'Sox'}

この方法で辞書が作成されると、他の辞書と同じ方法でその値にアクセスします。

>>>

>>> person
{'fname': 'Joe', 'lname': 'Fonebone', 'age': 51, 'spouse': 'Edna',
'children': ['Ralph', 'Betty', 'Joey'], 'pets': {'dog': 'Fido', 'cat': 'Sox'}}

>>> person['fname']
'Joe'
>>> person['age']
51
>>> person['children']
['Ralph', 'Betty', 'Joey']

サブリストまたはサブディクショナリの値を取得するには、追加のインデックスまたはキーが必要です。

>>>

>>> person['children'][-1]
'Joey'
>>> person['pets']['cat']
'Sox'

この例は、辞書の別の機能を示しています。辞書に含まれる値は同じタイプである必要はありません。 personでは、値の一部は文字列、1つは整数、1つはリスト、もう1つは別の辞書です。

辞書の値が同じタイプである必要はないのと同じように、キーも次のいずれでもありません。

>>>

>>> foo = {42: 'aaa', 2.78: 'bbb', True: 'ccc'}
>>> foo
{42: 'aaa', 2.78: 'bbb', True: 'ccc'}

>>> foo[42]
'aaa'
>>> foo[2.78]
'bbb'
>>> foo[True]
'ccc'

ここで、キーの1つは整数、1つは浮動小数点数、1つはブール値です。 これがどのように役立つかは明らかではありませんが、あなたは決して知りません。

汎用性の高いPython辞書がどのように使用されているかに注目してください。 MLB_teamでは、地理的に異なるいくつかの場所ごとに同じ情報(野球チーム名)が保持されます。 一方、personは、1人のさまざまなタイプのデータを格納します。

許可されるキーと値にはほとんど制限がないため、辞書を幅広い目的に使用できます。 しかし、いくつかあります。 読む!

辞書キーの制限

Pythonでは、ほぼすべてのタイプの値を辞書キーとして使用できます。 整数、浮動小数点数、およびブール値のオブジェクトがキーとして使用されるこの例を見ました。

>>>

>>> foo = {42: 'aaa', 2.78: 'bbb', True: 'ccc'}
>>> foo
{42: 'aaa', 2.78: 'bbb', True: 'ccc'}

型や関数などの組み込みオブジェクトも使用できます。

>>>

>>> d = {int: 1, float: 2, bool: 3}
>>> d
{: 1, : 2, : 3}
>>> d[float]
2

>>> d = {bin: 1, hex: 2, oct: 3}
>>> d[oct]
3

ただし、辞書キーには従わなければならない制限がいくつかあります。

まず、特定のキーは辞書に一度しか表示できません。 重複キーは許可されません。 辞書は各キーを対応する値にマッピングするため、特定のキーを複数回マッピングしても意味がありません。

上記のように、既存の辞書キーに値を割り当てると、キーは2回追加されず、既存の値が置き換えられます。

>>>

>>> MLB_team = {
...     'Colorado' : 'Rockies',
...     'Boston'   : 'Red Sox',
...     'Minnesota': 'Twins',
...     'Milwaukee': 'Brewers',
...     'Seattle'  : 'Mariners'
... }

>>> MLB_team['Minnesota'] = 'Timberwolves'
>>> MLB_team
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Timberwolves',
'Milwaukee': 'Brewers', 'Seattle': 'Mariners'}

同様に、ディクショナリの最初の作成中にキーを2回指定すると、2番目のオカレンスが最初のオカレンスをオーバーライドします。

>>>

>>> MLB_team = {
...     'Colorado' : 'Rockies',
...     'Boston'   : 'Red Sox',
...     'Minnesota': 'Timberwolves',
...     'Milwaukee': 'Brewers',
...     'Seattle'  : 'Mariners',
...     'Minnesota': 'Twins'
... }
>>> MLB_team
{'Colorado': 'Rockies', 'Boston': 'Red Sox', 'Minnesota': 'Twins',
'Milwaukee': 'Brewers', 'Seattle': 'Mariners'}

過ぎ去った、ティンバーウルブズ! あなたはNBAチームです。 並べ替えます。

第二に、辞書キーは不変のタイプでなければなりません。 整数、浮動小数点数、文字列、ブール値など、使い慣れたいくつかの不変型が辞書のキーとして機能する例を既に見てきました。

タプルは不変であるため、タプルは辞書キーにもなります。

>>>

>>> d = {(1, 1): 'a', (1, 2): 'b', (2, 1): 'c', (2, 2): 'd'}
>>> d[(1,1)]
'a'
>>> d[(2,1)]
'c'

tuplesに関する説明から、リストの代わりにタプルを使用する理由の1つは、不変の型が必要な状況があることを思い出してください。 これはそのうちの1つです。)

ただし、リストと辞書は変更可能であるため、リストも別の辞書も辞書キーとして機能しません。

>>>

>>> d = {[1, 1]: 'a', [1, 2]: 'b', [2, 1]: 'c', [2, 2]: 'd'}
Traceback (most recent call last):
  File "", line 1, in 
    d = {[1, 1]: 'a', [1, 2]: 'b', [2, 1]: 'c', [2, 2]: 'd'}
TypeError: unhashable type: 'list'

Technical Note:エラーメッセージに「ハッシュ不可」と表示されるのはなぜですか?

技術的には、オブジェクトを辞書キーとして使用するには不変である必要があると言うのはまったく正しくありません。 より正確には、オブジェクトはhashableである必要があります。これは、ハッシュ関数に渡すことができることを意味します。 ハッシュ関数は、任意のサイズのデータ​​を取得し、それをhash value(または単にハッシュ)と呼ばれる比較的単純な固定サイズの値にマップします。これは、テーブルのルックアップと比較に使用されます。

Pythonの組み込みhash()関数は、ハッシュ可能なオブジェクトのハッシュ値を返し、そうでないオブジェクトの例外を発生させます。

>>>

>>> hash('foo')
11132615637596761

>>> hash([1, 2, 3])
Traceback (most recent call last):
  File "", line 1, in 
TypeError: unhashable type: 'list'

これまでに学んだすべての組み込みの不変型はハッシュ可能ですが、可変コンテナ型(リストおよび辞書)はそうではありません。 したがって、現在の目的のために、ハッシュ可能および不変を多かれ少なかれ同義と考えることができます。

将来のチュートリアルでは、ハッシュ可能な可変オブジェクトに遭遇するでしょう。

辞書値の制限

対照的に、辞書の値に制限はありません。 文字通りまったくありません。 辞書の値には、リストや辞書などの可変型や、今後のチュートリアルで学習するユーザー定義オブジェクトなど、Pythonがサポートするあらゆる種類のオブジェクトを指定できます。

また、辞書に複数回現れる特定の値に対する制限もありません。

>>>

>>> d = {0: 'a', 1: 'a', 2: 'a', 3: 'a'}
>>> d
{0: 'a', 1: 'a', 2: 'a', 3: 'a'}
>>> d[0] == d[1] == d[2]
True

演算子と組み込み関数

stringslists、およびtuplesで使用できる多くの演算子と組み込み関数についてはすでに理解しています。 これらの一部は辞書でも機能します。

たとえば、inおよびnot in演算子は、指定されたオペランドが辞書のキーとして出現するかどうかに応じて、TrueまたはFalseを返します。

>>>

>>> MLB_team = {
...     'Colorado' : 'Rockies',
...     'Boston'   : 'Red Sox',
...     'Minnesota': 'Twins',
...     'Milwaukee': 'Brewers',
...     'Seattle'  : 'Mariners'
... }

>>> 'Milwaukee' in MLB_team
True
>>> 'Toronto' in MLB_team
False
>>> 'Toronto' not in MLB_team
True

ディクショナリにないキーにアクセスしようとしたときにエラーが発生しないように、in演算子を短絡評価と一緒に使用できます。

>>>

>>> MLB_team['Toronto']
Traceback (most recent call last):
  File "", line 1, in 
    MLB_team['Toronto']
KeyError: 'Toronto'

>>> 'Toronto' in MLB_team and MLB_team['Toronto']
False

2番目のケースでは、短絡評価のため、式MLB_team['Toronto']は評価されないため、KeyError例外は発生しません。

len()関数は、辞書内のキーと値のペアの数を返します。

>>>

>>> MLB_team = {
...     'Colorado' : 'Rockies',
...     'Boston'   : 'Red Sox',
...     'Minnesota': 'Twins',
...     'Milwaukee': 'Brewers',
...     'Seattle'  : 'Mariners'
... }
>>> len(MLB_team)
5

組み込み辞書メソッド

文字列とリストと同様に、辞書で呼び出すことができる組み込みメソッドがいくつかあります。 実際、場合によっては、リストメソッドと辞書メソッドは同じ名前を共有します。 (オブジェクト指向プログラミングの議論では、異なる型が同じ名前のメソッドを持つことは完全に受け入れられることがわかります。)

以下は、辞書に適用されるメソッドの概要です。

d.clear()

辞書をクリアします。

d.clear()は、すべてのキーと値のペアの辞書dを空にします。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}
>>> d
{'a': 10, 'b': 20, 'c': 30}

>>> d.clear()
>>> d
{}

d.get([, ])

キーがディクショナリに存在する場合、キーの値を返します。

Python辞書の.get()メソッドは、キーが存在するかどうかを事前にチェックしたり、エラーを発生させたりすることなく、辞書からキーの値を取得する便利な方法を提供します。

d.get(<key>)は、辞書d<key>を検索し、見つかった場合は関連する値を返します。 <key>が見つからない場合は、Noneを返します。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}

>>> print(d.get('b'))
20
>>> print(d.get('z'))
None

<key>が見つからず、オプションの<default>引数が指定されている場合、Noneの代わりにその値が返されます。

>>>

>>> print(d.get('z', -1))
-1

d.items()

辞書内のキーと値のペアのリストを返します。

d.items()は、dのキーと値のペアを含むタプルのリストを返します。 各タプルの最初の項目はキーであり、2番目の項目はキーの値です:

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}
>>> d
{'a': 10, 'b': 20, 'c': 30}

>>> list(d.items())
[('a', 10), ('b', 20), ('c', 30)]
>>> list(d.items())[1][0]
'b'
>>> list(d.items())[1][1]
20

d.keys()

辞書内のキーのリストを返します。

d.keys()は、d内のすべてのキーのリストを返します。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}
>>> d
{'a': 10, 'b': 20, 'c': 30}

>>> list(d.keys())
['a', 'b', 'c']

d.values()

辞書内の値のリストを返します。

d.values()は、dのすべての値のリストを返します。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}
>>> d
{'a': 10, 'b': 20, 'c': 30}

>>> list(d.values())
[10, 20, 30]

dの重複値は、発生した回数だけ返されます。

>>>

>>> d = {'a': 10, 'b': 10, 'c': 10}
>>> d
{'a': 10, 'b': 10, 'c': 10}

>>> list(d.values())
[10, 10, 10]

Technical Note:.items().keys().values()のメソッドは、実際にはview objectと呼ばれるものを返す。 辞書ビューオブジェクトは、キーと値のウィンドウに似ています。 実際には、これらのメソッドは辞書のキーと値のリストを返すと考えることができます。

d.pop([, ])

ディクショナリからキーが存在する場合は削除し、その値を返します。

<key>dに存在する場合、d.pop(<key>)<key>を削除し、関連する値を返します。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}

>>> d.pop('b')
20
>>> d
{'a': 10, 'c': 30}

<key>dにない場合、d.pop(<key>)KeyError例外を発生させます。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}

>>> d.pop('z')
Traceback (most recent call last):
  File "", line 1, in 
    d.pop('z')
KeyError: 'z'

<key>dになく、オプションの<default>引数が指定されている場合、その値が返され、例外は発生しません。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}
>>> d.pop('z', -1)
-1
>>> d
{'a': 10, 'b': 20, 'c': 30}

d.popitem()

辞書からキーと値のペアを削除します。

d.popitem()は、ランダムな任意のキーと値のペアをdから削除し、タプルとして返します。

>>>

>>> d = {'a': 10, 'b': 20, 'c': 30}

>>> d.popitem()
('c', 30)
>>> d
{'a': 10, 'b': 20}

>>> d.popitem()
('b', 20)
>>> d
{'a': 10}

dが空の場合、d.popitem()KeyError例外を発生させます。

>>>

>>> d = {}
>>> d.popitem()
Traceback (most recent call last):
  File "", line 1, in 
    d.popitem()
KeyError: 'popitem(): dictionary is empty'

d.update()

辞書を別の辞書または反復可能なキーと値のペアとマージします。

<obj>が辞書の場合、d.update(<obj>)<obj>のエントリをdにマージします。 <obj>の各キーについて:

  • キーがdに存在しない場合、<obj>のキーと値のペアがdに追加されます。

  • キーがすでにdに存在する場合、そのキーのdの対応する値は、<obj>の値に更新されます。

以下に、2つの辞書をマージした例を示します。

>>>

>>> d1 = {'a': 10, 'b': 20, 'c': 30}
>>> d2 = {'b': 200, 'd': 400}

>>> d1.update(d2)
>>> d1
{'a': 10, 'b': 200, 'c': 30, 'd': 400}

この例では、キー'b'はすでにd1に存在するため、その値は200に更新され、そのキーの値はd2からのものになります。 ただし、d1にはキー'd'がないため、キーと値のペアはd2から追加されます。

<obj>は、dict()関数を使用して辞書を定義する場合と同様に、キーと値のペアのシーケンスにすることもできます。 たとえば、<obj>はタプルのリストとして指定できます。

>>>

>>> d1 = {'a': 10, 'b': 20, 'c': 30}
>>> d1.update([('b', 200), ('d', 400)])
>>> d1
{'a': 10, 'b': 200, 'c': 30, 'd': 400}

または、マージする値をキーワード引数のリストとして指定できます。

>>>

>>> d1 = {'a': 10, 'b': 20, 'c': 30}
>>> d1.update(b=200, d=400)
>>> d1
{'a': 10, 'b': 200, 'c': 30, 'd': 400}

結論

このチュートリアルでは、Pythondictionaryの基本的なプロパティについて説明し、辞書データにアクセスして操作する方法を学びました。

Listsdictionariesは、最も頻繁に使用されるPythonタイプの2つです。 ご覧のとおり、これらにはいくつかの類似点がありますが、要素へのアクセス方法が異なります。 リスト要素は順序に基づいた数値インデックスによってアクセスされ、辞書要素はキーによってアクセスされます

この違いのため、リストと辞書は異なる状況に適している傾向があります。 これで、与えられた状況に対してどちらかが最良であると感じられるはずです。

次に、Pythonsetsについて学習します。 セットは別の複合データ型ですが、リストまたは辞書とはまったく異なります。

__ Take the Quiz:インタラクティブな「PythonDictionaries」クイズで知識をテストします。 完了すると、学習の進捗状況を経時的に追跡できるようにスコアを受け取ります。