详细探究Python中的字典容器

dictionary

我们都曾经使用过语言词典来查找不认识的单词的定义。语言词典针对给定的单词(比如 python)提供一组标准的信息。这种系统将定义和其他信息与实际的单词关联(映射)起来。使用单词作为键定位器来寻找感兴趣的信息。这种概念延伸到 Python 编程语言中,就成了特殊的容器类型,称为 dictionary。

dictionary 数据类型在许多语言中都存在。它有时候称为关联 数组(因为数据与一个键值相关联),或者作为散列表。但是在 Python 中,dictionary 是一个很好的对象,因此即使是编程新手也很容易在自己的程序中使用它。按照正式的说法,Python 中的 dictionary 是一种异构的、易变的映射容器数据类型。
创建 dictionary

本系列中前面的文章介绍了 Python 编程语言中的一些容器数据类型,包括 tuple、string 和 list(参见 参考资料)。这些容器的相似之处是它们都是基于序列的。这意味着要根据元素在序列中的位置访问这些集合中的元素。所以,给定一个名为 a 的序列,就可以使用数字索引(比如 a[0] )或片段(比如 a[1:5])来访问元素。Python 中的 dictionary 容器类型与这三种容器类型的不同之处在于,它是一个无序的集合。不是按照索引号,而是使用键值来访问集合中的元素。这意味着构造 dictionary 容器比 tuple、string 或 list 要复杂一些,因为必须同时提供键和相应的值,如清单 1 所示。
清单 1. 在 Python 中创建 dictionary,第 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 中创建 dictionary 要使用花括号和以冒号分隔的键-值组合。如果没有提供键-值组合,那么就会创建一个空的 dictionary。使用一个键-值组合,就会创建具有一个元素的 dictionary,以此类推,直至您需要的任何规模。与任何容器类型一样,可以使用内置的 len 方法查明集合中元素的数量。

前面的示例还演示了关于 dictionary 容器的另一个重要问题。键并不限制为整数;它可以是任何不易变的数据类型,包括 integer、float、tuple 或 string。因为 list 是易变的,所以它不能作为 dictionary 中的键。但是 dictionary 中的值可以是任何数据类型的。

最后,这个示例说明了 Python 中 dictionary 的底层数据类型是 dict 对象。要进一步了解如何使用 Python 中的 dictionary,可以使用内置的帮助解释器来了解 dict 类,如清单 2 所示。
清单 2. 获得关于 dictionary 的帮助

>>> 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 类的帮助指出,可以使用构造函数直接创建 dictionary,而不使用花括号。既然与其他容器数据类型相比,在创建 dictionary 时必须提供更多的数据,那么这些创建方法比较复杂也就不足为奇了。但是,在实践中使用 dictionary 并不难,如清单 3 所示。
清单 3. 在 Python 中创建 dictionary,第 2 部分

>>> 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

可以看到,创建 dictionary 需要键值和数据值。第一次从 list 创建 dictionary 的尝试失败了,这是因为没有匹配的键-数据值对。第二个和第三个示例演示了如何正确地创建 dictionary:在第一种情况下,使用一个 list,其中的每个元素都是一个 tuple;在第二种情况下,也使用一个 list,但是其中的每个元素是另一个 list。在这两种情况下,内层容器都用于获得键到数据值的映射。

直接创建 dict 容器的另一个方法是直接提供键到数据值的映射。这种技术允许显式地定义键和与其对应的值。这个方法其实用处不大,因为可以使用花括号完成相同的任务。另外,如前面的例子所示,在采用这种方式时对于键不能使用数字,否则会导致抛出一个异常。
访问和修改 dictionary

创建了 dictionary 之后,需要访问其中包含的数据。访问方式与访问任何 Python 容器数据类型中的数据相似,如清单 4 所示。
清单 4. 访问 dictionary 中的元素

>>> 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 所示,可以添加新的键到数据值的映射,可以修改现有的映射,还可以删除映射。
清单 5. 修改 dictionary

>>> 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 所示。
清单 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 中的特定次序。
用 dictionary 进行编程

作为正式的 Python 数据类型,dictionary 支持其他较简单数据类型所支持的大多数操作。这些操作包括一般的关系操作符,比如 <、> 和 ==,如清单 7 所示。
清单 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 所示,这些检查很容易执行。
清单 8. 条件测试和 dictionary

>>> 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 所示。
清单 9. 迭代和 dictionary

>>> 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() 方法允许同时遍历键到数据值的映射。

dictionary:另一种强大的 Python 容器

本文讨论了 Python dictionary 数据类型。dictionary 是一种异构的、易变的容器,依赖键到数据值的映射(而不是特定的数字次序)来访问容器中的元素。访问、添加和删除 dictionary 中的元素都很简单,而且 dictionary 很容易用于复合语句,比如 if 语句或 for 循环。可以在 dictionary 中存储所有不同类型的数据,可以按照名称或其他复合键值(比如 tuple)访问这些数据,所以 Python dictionary 使开发人员能够编写简洁而又强大的编程语句。

(0)

相关推荐

  • python 容器总结整理

    python 容器总结整理 list 可变数组 tuple 不可变数组 dict 键值对(key-value)的字典(dictionary) 初始化: a={'lyt':90} 添加: a['zxw']=91 访问: 1.a[key] 不存在会出错 2.a.get(key) 不存在返回None 3.a.get(key,val1) 不存在返回指定的val1 ####判断: >>>key in a True/False 删除: a.pop(key) 存在返回对应的val,不存在报错 注意,k

  • Python中Collections模块的Counter容器类使用教程

    1.collections模块 collections模块自Python 2.4版本开始被引入,包含了dict.set.list.tuple以外的一些特殊的容器类型,分别是: OrderedDict类:排序字典,是字典的子类.引入自2.7. namedtuple()函数:命名元组,是一个工厂函数.引入自2.6. Counter类:为hashable对象计数,是字典的子类.引入自2.7. deque:双向队列.引入自2.4. defaultdict:使用工厂函数创建字典,使不用考虑缺失的字典键.引

  • python脚本监控docker容器

    本文实例为大家分享了python脚本监控docker容器的方法,供大家参考,具体内容如下 脚本功能: 1.监控CPU使用率 2.监控内存使用状况 3.监控网络流量 具体代码: #!/usr/bin/env python # --*-- coding:UTF-8 --*-- import sys import tab import re import os import time from docker import Client import commands keys_container_st

  • 使用IPython来操作Docker容器的入门指引

    现在Docker是地球上最炙手可热的项目之一,就意味着人民实际上不仅仅是因为这个才喜欢它. 话虽如此,我非常喜欢使用容器,服务发现以及所有被创造出的新趣的点子和领域来切换工作作为范例. 这个文章中我会简要介绍使用python中的docker-py模块来操作Docker 容器,这里会使用我喜爱的编程工具IPython. 安装docker-py 首先需要docker-py.注意这里的案例中我将会使用Ubuntu Trusty 14.04版本. $ pip install docker-py IPyh

  • 详细探究Python中的字典容器

    dictionary 我们都曾经使用过语言词典来查找不认识的单词的定义.语言词典针对给定的单词(比如 python)提供一组标准的信息.这种系统将定义和其他信息与实际的单词关联(映射)起来.使用单词作为键定位器来寻找感兴趣的信息.这种概念延伸到 Python 编程语言中,就成了特殊的容器类型,称为 dictionary. dictionary 数据类型在许多语言中都存在.它有时候称为关联 数组(因为数据与一个键值相关联),或者作为散列表.但是在 Python 中,dictionary 是一个很好

  • Python中遍历字典过程中更改元素导致异常的解决方法

    先来回顾一下Python中遍历字典的一些基本方法: 脚本: #!/usr/bin/python dict={"a":"apple","b":"banana","o":"orange"} print "##########dict######################" for i in dict: print "dict[%s]=" % i,

  • python中的字典操作及字典函数

    字典 dict_fruit = {'apple':'苹果','banana':'香蕉','cherry':'樱桃','avocado':'牛油果','watermelon':'西瓜'} 字典的操作 #字典的遍历方式 #默认遍历(遍历key) for value in dict_fruit: print(value) ''''' 遍历出的值: watermelon apple cherry avocado banana ''' #使用key遍历(与默认遍历一样) for key in dict_f

  • 详细介绍Python中的set集合

    目录 Python中的set集合 一.集合是什么? 二.set集合怎么用? 1.创建set集合 2.删除set集合 3.访问set集合元素 4.删除集合中的元素 5.向集合中添加元素 三.set集合的交并补 1.交集 2.并集 3.差集 四.set中的其他方法 五.frozenset 集合 Python中的set集合 一.集合是什么? 集合是什么呢?相信读者朋友们哪怕是没有用过集合这个数据类型.也一定在数学课堂上听过集合这个名词.数学中的集合是一个基本概念,说白了一堆不重复的数字可以组成一个集合

  • Python中创建字典的几种方法总结(推荐)

    1.传统的文字表达式: >>> d={'name':'Allen','age':21,'gender':'male'} >>> d {'age': 21, 'name': 'Allen', 'gender': 'male'} 如果你可以事先拼出整个字典,这种方式是很方便的. 2.动态分配键值: >>> d={} >>> d['name']='Allen' >>> d['age']=21 >>> d[

  • Python中的字典遍历备忘

    备忘一下python中的字典如何遍历,没有什么太多技术含量.仅供作为初学者的我参考. 复制代码 代码如下: #!/usr/bin/env python # coding=utf-8 demoDict = {'1':'Chrome', '2':'Android'} for key in demoDict.keys():     print key for value in demoDict.values():     print value for key in demoDict:     pri

  • 在Python中合并字典模块ChainMap的隐藏坑【推荐】

    在Python中,当我们有两个字典需要合并的时候,可以使用字典的 update 方法,例如: a = {'a': 1, 'b': 2} b = {'x': 3, 'y': 4} a.update(b) print(a) 运行效果如下图所示: 然而,这个方法有一个问题--它会改变其中一个字典.如果我们不想改变原有的两个字典,那么我们必需要单独再创建一个字典: a = {'a': 1, 'b': 2} b = {'x': 3, 'y': 4} c = dict(a) c.update(b) prin

  • 解决python中遇到字典里key值为None的情况,取不出来的问题

    在python 命令行界面里,是可以去取key为None的value值. 在脚本里面就取不出了,可以用如下的方式解决. hosts = {"a":"111", "None":b, "c":"333"} hname = "" for (k,v) in hosts.items(): if k == None: print " value=%s " % (v) else:

  • 关于探究python中sys.argv时遇到的问题详解

    自动化任务 这是一篇关于我在自己学习python自动化办公中遇到的问题的笔记. 关于文章读写 我用到的书是<python编程快速上手>,在学习第八章时遇到了理解上的困难.问题主要是在接触sys.argv和在创建bat文件时,出现了理解上的障碍. sys.argv这个函数是我们写python脚本中最常用的一个函数. sys是Python的一个「标准库」,也就是官方出的「模块」,是「System」的简写,封装了一些系统的信息和接口. 官方的文档参考:https://docs.python.org/

  • Python中的字典到底是有序的吗

    之前写了文章介绍python中的列表和字典,在文章中描述到了python中的列表是有序的,字典是无序的,后来有粉丝在群里提醒我,说python3.6的版本之后,字典是有序的,因此,我找了一个低版本的python来验证一下效果: 首先,从官网下载python3.4的版本,然后编写一行代码验证一下打印字典的所有key.查看打印出来的key的顺序: Python3.6以下版本:(以3.4版本为例) 你该不会以为只有使用keys()函数是无序的吧: 从上图可以看出,分别在cmd窗口和pycharm中打印

随机推荐