私たちは皆、知らない単語の定義を調べるために言語辞書を使用したことがあります。言語辞書は、特定の単語 (Python など) に関する標準的な情報セットを提供します。このシステムは、定義やその他の情報を実際の単語に関連付け (マッピング) します。単語をキーロケーターとして使用して、関心のある情報を見つけます。この概念は Python プログラミング言語にも拡張され、辞書と呼ばれる特殊なコンテナー タイプになります。
辞書データ型は多くの言語に存在します。これは、連想配列 (データがキー値に関連付けられているため) またはハッシュ テーブルと呼ばれることもあります。しかし、Python では辞書は優れたオブジェクトなので、初心者プログラマーでも独自のプログラムで簡単に使用できます。公式に言えば、Python の辞書は異種の変更可能なマッピング コンテナ データ型です。
このシリーズの前の記事では、タプル、文字列、リストなど、Python プログラミング言語のコンテナー データ型のいくつかを紹介しました (「参考文献」を参照)。これらのコンテナはシーケンスベースであるという点で似ています。これは、これらのコレクション内の要素がシーケンス内の位置に基づいてアクセスされることを意味します。したがって、 a という名前のシーケンスを指定すると、数値インデックス ( a[0] など) またはフラグメント ( a[1:5] など) を使用して要素にアクセスできます。 Python の辞書コンテナ タイプは、順序付けされていないコレクションであるという点で、これら 3 つのコンテナ タイプとは異なります。インデックス番号を使用する代わりに、キー値を使用してコレクション内の要素にアクセスします。これは、リスト 1 に示すように、キーと対応する値の両方を指定する必要があるため、辞書コンテナーの構築はタプル、文字列、またはリストよりも少し複雑であることを意味します。
>>> d = {0: 'zero', 1: 'one', 2 : 'two', 3 : 'three', 4 : 'four', 5: 'five'} >>> d {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'} >>> len(d) >>> type(d) # Base object is the dict class <type 'dict'> >>> d = {} # Create an empty dictionary >>> len(d) >>> d = {1 : 'one'} # Create a single item dictionary >>> d {1: 'one'} >>> len(d) >>> d = {'one' : 1} # The key value can be non-numeric >>> d {'one': 1} >>> d = {'one': [0, 1,2 , 3, 4, 5, 6, 7, 8, 9]} >>> d {'one': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]}
この例に示すように、Python での辞書の作成では、中括弧とコロンで区切られたキーと値の組み合わせを使用します。キーと値の組み合わせが指定されていない場合は、空の辞書が作成されます。キーと値の組み合わせを使用すると、1 つの要素を含む辞書が必要なサイズまで作成されます。他のコンテナ タイプと同様に、組み込みの len メソッドを使用してコレクション内の要素の数を確認できます。
前の例では、辞書コンテナに関する別の重要な問題も示しています。キーは整数に限定されません。整数、浮動小数点、タプル、文字列などの不変のデータ型を使用できます。リストは変更可能であるため、辞書のキーとして使用できません。ただし、ディクショナリ内の値は任意のデータ型にすることができます。
最後に、この例は、Python の辞書の基礎となるデータ型が dict オブジェクトであることを示しています。 Python での辞書の使用についてさらに詳しく知るには、リスト 2 に示すように、組み込みのヘルプ インタープリターを使用して dict クラスについて学ぶことができます。
>>> help(dict)on class dict in module __builtin__: dict(object) | dict() -> new empty dictionary. | dict(mapping) -> new dictionary initialized from a mapping object's | (key, value) pairs. | dict(seq) -> new dictionary initialized as if via: | d = {} | for k, v in seq: | d[k] = v | dict(**kwargs) -> new dictionary initialized with the name=value pairs | in the keyword argument list. For example: dict(one=1, two=2) | | Methods defined here: | | __cmp__(...) | x.__cmp__(y) <==> cmp(x,y) | | __contains__(...) | x.__contains__(y) <==> y in x | | __delitem__(...) | x.__delitem__(y) <==> del x[y] ...
dict クラスのヘルプには、中括弧を使用せずにコンストラクターを直接使用して辞書を作成できることが記載されています。ディクショナリを作成する際には、他のコンテナ データ タイプよりも多くのデータを提供する必要があるため、これらの作成方法が複雑になるのは当然のことです。ただし、リスト 3 に示すように、実際に辞書を使用することは難しくありません。
>>> l = [0, 1,2 , 3, 4, 5, 6, 7, 8, 9] >>> d = dict(l)(most recent call last): File "<stdin>", line 1, in ?: can't convert dictionary update sequence element #0 to a sequence >>> l = [(0, 'zero'), (1, 'one'), (2, 'two'), (3, 'three')] >>> d = dict(l) >>> d {0: 'zero', 1: 'one', 2: 'two', 3: 'three'} >>> l = [[0, 'zero'], [1, 'one'], [2, 'two'], [3, 'three']] >>> d {0: 'zero', 1: 'one', 2: 'two', 3: 'three'} >>> d = dict(l) >>> d {0: 'zero', 1: 'one', 2: 'two', 3: 'three'} >>> d = dict(zero=0, one=1, two=2, three=3) >>> d {'zero': 0, 'three': 3, 'two': 2, 'one': 1} >>> d = dict(0=zero, 1=one, 2=two, 3=three): keyword can't be an expression
ご覧のとおり、辞書を作成するにはキー値とデータ値が必要です。リストからディクショナリを作成しようとする最初の試みは、一致するキーとデータ値のペアがないため失敗します。 2 番目と 3 番目の例は、辞書を正しく作成する方法を示しています。最初の例では、各要素がタプルであるリストを使用します。2 番目の例では、リストも使用しますが、その中の各要素は別のリストです。どちらの場合も、内部コンテナーはキーとデータ値のマッピングを取得するために使用されます。
dict コンテナを直接作成するもう 1 つの方法は、キーとデータ値のマッピングを直接提供することです。この手法により、キーとそれに対応する値を明示的に定義できます。中括弧を使用して同じタスクを実行できるため、この方法は実際にはあまり有用ではありません。また、前の例で示したように、このメソッドを使用する場合、キーに数字を使用することはできません。使用しない場合は、例外がスローされます。
辞書へのアクセスと変更
辞書を作成した後、辞書に含まれるデータにアクセスする必要があります。アクセスは、リスト 4 に示すように、Python コンテナー データ型のデータにアクセスするのと似ています。
>>> d = dict(zero=0, one=1, two=2, three=3) >>> d {'zero': 0, 'three': 3, 'two': 2, 'one': 1} >>> d['zero'] >>> d['three'] >>> d = {0: 'zero', 1: 'one', 2 : 'two', 3 : 'three', 4 : 'four', 5: 'five'} >>> d[0] 'zero' >>> d[4] 'four' >>> d[6](most recent call last): File "<stdin>", line 1, in ?: 6 >>> d[:-1](most recent call last): File "<stdin>", line 1, in ?: unhashable type
可以看到,从字典(dictionary)中获取数据值的过程几乎与从任何容器类型中获取数据完全一样。在容器名后面的方括号中放上键值。当然,字典(dictionary)可以具有非数字的键值,如果您以前没有使用过这种数据类型,那么适应这一点需要些时间。因为在字典(dictionary)中次序是不重要的(dictionary 中数据的次序是任意的),所以可以对其他容器数据类型使用的片段功能,对于 字典(dictionary)是不可用的。试图使用片段或者试图从不存在的键访问数据就会抛出异常,指出相关的错误。
Python 中的字典(dictionary)容器也是易变的数据类型,这意味着在创建它之后可以修改它。如清单 5 所示,可以添加新的键到数据值的映射,可以修改现有的映射,还可以删除映射。
>>> d = {0: 'zero', 1: 'one', 2: 'two', 3: 'three'} >>> d[0] 'zero' >>> d[0] = 'Zero' >>> d {0: 'Zero', 1: 'one', 2: 'two', 3: 'three'} >>> d[4] = 'four' >>> d[5] = 'five' >>> d {0: 'Zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'} >>> del d[0] >>> d {1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'} >>> d[0] = 'zero' >>> d {0: 'zero', 1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five'}
清单 5 演示了几个重点。首先,修改数据值是很简单的:将新的值分配给适当的键。其次,添加新的键到数据值的映射也很简单:将相关数据分配给新的键值。Python 自动进行所有处理。不需要调用 append 这样的特殊方法。对于 dictionary 容器,次序是不重要的,所以这应该好理解,因为不是在字典(dictionary)后面附加映射,而是将它添加到容器中。最后,删除映射的办法是使用 del 操作符以及应该从容器中删除的键。
在清单 5 中有一个情况看起来有点儿怪,键值是按照数字次序显示的,而且这个次序与插入映射的次序相同。不要误解 —— 情况不总是这样的。Python 字典(dictionary)中映射的次序是任意的,对于不同的 Python 安装可能会有变化,甚至多次使用同一 Python 解释器运行相同代码也会有变化。如果在一个字典(dictionary)中使用不同类型的键和数据值,那么就很容易看出这一点,如清单 6 所示。
>>> d = {0: 'zero', 'one': 1} >>> d {0: 'zero', 'one': 1} >>> d[0] 'zero' >>> type(d[0]) <type 'str'> >>> d['one'] >>> type(d['one']) <type 'int'> >>> d['two'] = [0, 1, 2] >>> d {0: 'zero', 'two': [0, 1, 2], 'one': 1} >>> d[3] = (0, 1, 2, 3) >>> d {0: 'zero', 3: (0, 1, 2, 3), 'two': [0, 1, 2], 'one': 1} >>> d[3] = 'a tuple' >>> d {0: 'zero', 3: 'a tuple', 'two': [0, 1, 2], 'one': 1}
如这个例子所示,可以在一个字典(dictionary)中使用不同数据类型的键和数据值。还可以通过修改字典(dictionary)添加新的类型。最后,产生的 dictionary 的次序并不与插入数据的次序匹配。本质上,字典(dictionary)中元素的次序是由 Python 字典(dictionary)数据类型的实际实现控制的。新的 Python 解释器很容易改变这一次序,所以一定不要依赖于元素在字典(dictionary)中的特定次序。
作为正式的 Python 数据类型,字典(dictionary)支持其他较简单数据类型所支持的大多数操作。这些操作包括一般的关系操作符,比如 <、> 和 ==,如清单 7 所示。
>>> d1 = {0: 'zero'} >>> d2 = {'zero':0} >>> d1 < d2 >>> d2 = d1 >>> d1 < d2 >>> d1 == d2 >>> id(d1) >>> id(d2) >>> d2 = d1.copy() >>> d1 == d2 >>> id(d1) >>> id(d2)
前面的示例创建两个字典(dictionary)并使用它们测试 < 关系操作符。尽管很少以这种方式比较两个字典(dictionary);但是如果需要,可以这样做。
然后,这个示例将赋值给变量 d1 的字典(dictionary)赋值给另一个变量 d2。注意,内置的 id() 方法对于 d1 和 d2 返回相同的标识符值,这说明这不是复制操作。要想复制字典(dictionary) ,可以使用 copy() 方法。从这个示例中的最后几行可以看出,副本与原来的字典(dictionary)完全相同,但是容纳这字典(dictionary)的变量具有不同的标识符。
在 Python 程序中使用字典(dictionary)时,很可能希望检查字典(dictionary)中是否包含特定的键或值。如清单 8 所示,这些检查很容易执行。
>>> d = {0: 'zero', 3: 'a tuple', 'two': [0, 1, 2], 'one': 1} >>> d.keys() [0, 3, 'two', 'one'] >>> if 0 in d.keys(): ... print 'True' ... >>> if 'one' in d: ... print 'True' ... >>> if 'four' in d: ... print 'Dictionary contains four' ... elif 'two' in d: ... print 'Dictionary contains two' ... contains two
测试字典(dictionary)中键或数据值的成员关系是很简单的。dictionary 容器数据类型提供几个内置方法,包括 keys() 方法和 values() 方法(这里没有演示)。这些方法返回一个列表,其中分别包含进行调用的字典(dictionary)中的键或数据值。
因此,要判断某个值是否是字典(dictionary)中的键,应该使用 in 操作符检查这个值是否在调用 keys() 方法所返回的键值列表中。可以使用相似的操作检查某个值是否在调用 values() 方法所返回的数据值列表中。但是,可以使用字典(dictionary)名作为简写表示法。这是有意义的,因为一般希望知道某个数据值(而不是键值)是否在字典(dictionary)中。
在 “Discover Python, Part 6” 中,您看到了使用 for 循环遍历容器中的元素是多么容易。同样的技术也适用于 Python 字典(dictionary),如清单 9 所示。
>>> d = {0: 'zero', 3: 'a tuple', 'two': [0, 1, 2], 'one': 1} >>> for k in d.iterkeys(): ... print d[k] ... tuple [0, 1, 2] >>> for v in d.itervalues(): ... print v ... tuple [0, 1, 2] >>> for k, v in d.iteritems(): ... print 'd[',k,'] = ',v ... [ 0 ] = zero[ 3 ] = a tuple[ two ] = [0, 1, 2][ one ] = 1
这个示例演示了遍历字典(dictionary)的三种方式:使用从 iterkeys()、itervalues() 或 iteritems() 方法返回的 Python 迭代器。(顺便说一下,可以通过在字典(dictionary)上直接调用适当方法,比如 d.iterkeys(),从而检查这些方法是否返回一个迭代器而不是容器数据类型。)iterkeys() 方法允许遍历字典(dictionary)的键,而 itervalues() 方法允许遍历字典(dictionary)包含的数据值。另一方面,iteritems() 方法允许同时遍历键到数据值的映射。
本文讨论了 Python 字典(dictionary)数据类型。字典(dictionary)是一种异构的、易变的容器,依赖键到数据值的映射(而不是特定的数字次序)来访问容器中的元素。访问、添加和删除字典(dictionary)中的元素都很简单,而且字典(dictionary)很容易用于复合语句,比如 if 语句或 for 循环。可以在字典(dictionary)中存储所有不同类型的数据,可以按照名称或其他复合键值(比如 tuple)访问这些数据,所以 Python 字典(dictionary)使开发人员能够编写简洁而又强大的编程语句。
以上がPython 辞書コンテナの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。