Python基础:映射(字典)
一、概述
映射类型(Mapping Types)是一种关联式的容器类型,它存储了对象与对象之间的映射关系。
字典(dict)是Python中唯一的映射类型,它是存储了一个个 键值对(由 键 映射到 值)的关联容器。其中,键(key)必须是可哈希的Python对象,而 值(value)可以是任何Python对象。在功能上,Python中的字典类似于C++中的map。
Python中最强大、最灵活的数据类型当属 列表 和 字典,以下是对这两种数据类型的简单比较:
比较点 | 列表 | 字典 |
---|---|---|
表示方法 | [],[1, 2] | {},{'a': 1, 'b': 2} |
访问元素的方式 | 索引 | 键 |
有序性 | 有序 | 无序 |
可变性 | 可变 | 可变 |
可操作性 | 操作丰富 | 操作丰富 |
表征的数据结构 | 数组、堆栈、队列等 | 哈希表等 |
二、操作
字典支持的主要操作如下:
操作 | 说明 |
---|---|
class dict(other) | 创建字典(other可以是字典、(key, value)对的迭代器或关键字参数) |
dict.fromkeys(seq[, value]) | 创建字典:用序列seq中的元素作为键,值全为value(未指定,则默认为None) |
len(d) | 返回字典d的长度(即d中元素的个数) |
d[key] | 如果键key在字典d中,则返回其中key对应的值;否则抛出KeyError异常 |
d[key] = value | 设置d[key]的值为value(存在则修改,不存在则添加) |
del d[key] | 如果键key在字典d中,则从字典d中删除d[key];否则抛出KeyError异常 |
key in d | 如果key在字典d中,返回True;否则,返回False |
key not in d | 如果key在字典d中,返回False;否则,返回True |
iter(d) | 同iterkeys() |
d.clear() | 删除字典d中的所有元素 |
d.copy() | 返回字典d的浅拷贝 |
d.get(key[, default]) | 如果key在字典d中,则返回d[key];否则返回default(未指定,则默认为None) |
d.has_key(key) | 同key in d(推荐使用key in d) |
d.items() | 返回包含字典d中的(key, value)对的列表 |
d.iteritems() | 迭代版的items():返回迭代器 |
d.iterkeys() | 迭代版的keys():返回迭代器 |
d.itervalues() | 迭代版的values():返回迭代器 |
d.keys() | 返回包含字典d中的键的列表 |
d.pop(key[, default]) | 如果key在字典d中,则返回并删除d[key];否则返回default(未指定,则抛出KeyError异常) |
d.popitem() | 返回并删除字典d中的任意一个元素(如果d为空,则抛出KeyError异常) |
d.setdefault(key[, default]) | 如果key在字典d中,则返回d[key];否则执行d[key] = default,并返回default(未指定,则默认为None) |
d.update([other]) | 将other中的(key, value)对添加到字典d中(other可以是字典、(key, value)对的迭代器或关键字参数) |
d.values() | 返回包含字典d中的值的列表 |
d.viewitems() | 返回字典d的元素视图 |
d.viewkeys() | 返回字典d的键视图 |
d.viewvalues() | 返回字典d的值视图 |
以上操作的示例如下:
>>> a = {'one': 1, 'two': 2, 'three': 3}
>>> b = dict(one=1, two=2, three=3)
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d
True
>>> d = dict.fromkeys(['a', 'b', 'c'])
>>> d
{'a': None, 'c': None, 'b': None}
>>> d = dict.fromkeys(['a', 'b', 'c'], 6)
>>> d
{'a': 6, 'c': 6, 'b': 6}
>>> len(d)
3
>>> d.clear()
>>> d
{}
>>> d = a.copy()
>>> d
{'one': 1, 'three': 3, 'two': 2}
>>> d['three']
3
>>> d['four'] = 4
>>> d
{'four': 4, 'one': 1, 'three': 3, 'two': 2}
>>> del d['one']
>>> d
{'four': 4, 'three': 3, 'two': 2}
>>> 'four' in d, 'four' not in d
(True, False)
>>> d.has_key('four')
True
>>> d.get('one'), d.get('one', 10)
(None, 10)
>>> for k in d:
... print k,
...
four three two
>>> for k in iter(d):
... print k,
...
four three two
>>> for k in d.keys():
... print k,
...
four three two
>>> for k in d.iterkeys():
... print k,
...
four three two
>>> for k in d.viewkeys():
... print k,
...
four three two
>>> for v in d.values():
... print v,
...
4 3 2
>>> for v in d.itervalues():
... print v,
...
4 3 2
>>> for v in d.viewvalues():
... print v,
...
4 3 2
>>> for i in d.items():
... print i,
...
('four', 4) ('three', 3) ('two', 2)
>>> for i in d.iteritems():
... print i,
...
('four', 4) ('three', 3) ('two', 2)
>>> for i in d.viewitems():
... print i,
...
('four', 4) ('three', 3) ('two', 2)
>>> d.setdefault('two')
2
>>> d
{'four': 4, 'three': 3, 'two': 2}
>>> d.setdefault('one', 1)
1
>>> d
{'four': 4, 'one': 1, 'three': 3, 'two': 2}
>>> d.update(five=1)
>>> d
{'four': 4, 'one': 1, 'five': 1, 'three': 3, 'two': 2}
>>> d.update({'six': 6})
>>> d
{'four': 4, 'five': 1, 'two': 2, 'six': 6, 'three': 3, 'one': 1}
>>> d.pop('four')
4
>>> d
{'five': 1, 'two': 2, 'six': 6, 'three': 3, 'one': 1}
>>> d.popitem()
('five', 1)
>>> d
{'two': 2, 'six': 6, 'three': 3, 'one': 1}
三、字典特性
1、有序与无序
从概念上讲,字典提供了这样一种抽象:容器中的元素之间完全独立(于是也没有先后顺序),“键”是访问元素的唯一方式。在这种 抽象层面 上,字典是 无序 的。
从实现上讲,字典其实是由 哈希表 实现的。而哈希表的基本思想是:通过 哈希函数(hash function)将“键”转换为“索引”,再使用“索引”去访问 连续列表(如C中的数组)中的元素。由此可知,在哈希表中:一方面,元素本质上是存储在一个连续列表中的,因此是 有序 的;另一方面,用户无法确定元素在连续列表中的实际位置(只能使用“键”去访问元素,而“键”与“索引”的映射关系是由哈希函数在内部指定的),因此又是 无序 的。
因此在 实现层面 上,字典同时具备了 无序 和 有序 的特点:
- 无序体现在:字典中元素的排列顺序与添加顺序无关
- 有序体现在:在字典保持不变的情况下,字典中元素的排列顺序是固定的
上图对应的示例如下:
# 无序
>>> d = {}
>>> d['a'] = 1
>>> d
{'a': 1}
>>> d['b'] = 2
>>> d
{'a': 1, 'b': 2}
>>> d['c'] = 3
>>> d
{'a': 1, 'c': 3, 'b': 2}
# 有序
>>> for k in d: # 键的顺序固定
... print k,
...
a c b
>>> for v in d.values(): # 值的顺序固定
... print v,
...
1 3 2
>>> for i in d.items(): # 元素的顺序固定
... print i,
...
('a', 1) ('c', 3) ('b', 2)
2、字典的键
字典的键具有以下特性:
1)可哈希的(hashable)
只有 可哈希的 对象才能作为字典的键,一个可哈希的对象必须满足以下两个条件:
- 该对象在其生命周期内有一个不变的哈希值(需要实现
__hash__()
方法) - 该对象是可比较的(需要实现
__eq__()
或__cmp__()
方法)
Python中可哈希的对象有:
- 数值、字符串,以及只含有数值或字符串的元组
- 用户自定义类的实例(默认是可哈希的,也可以通过实现
__hash__()
和__cmp__()
来修改默认行为)
2)哈希等价键
假设有字典d的两个键:keyA和keyB,我们称keyA和keyB是 哈希等价键(自己杜撰的名词),如果keyA和keyB满足以下两个条件:
- hash(keyA) == hash(keyB)
- cmp(keyA, keyB) == 0
如果keyA和keyB是哈希等价键,那么它们将被视为完全相同的两个键,于是d[keyA]和d[keyB]会指向同一个字典元素。
例如,1和1.0就满足上述两个条件,因此是哈希等价键:
>>> hash(1), hash(1.0)
(1, 1)
>>> cmp(1, 1.0)
0
>>> d = {}
>>> d[1] = 'int 1'
>>> d
{1: 'int 1'}
>>> d[1.0] = 'float 1'
>>> d
{1: 'float 1'}
对于用户自定义的类实例,默认情况下(即没有实现__hash__()
和__cmp__()
时),hash(...)和cmp(...)的结果与 id() 有关(参考 hashable 和 __cmp__())。默认情况下,一个自定义类的任意两个实例都不是哈希等价键:
>>> class A: pass
...
>>> a1 = A()
>>> a2 = A()
>>> hash(a1), hash(a2)
(-1064359592, -1064359600)
>>> cmp(a1, a2)
1
>>> d = {}
>>> d[a1] = 'a1'
>>> d
{<__main__.A instance at 0x8f2958c>: 'a1'}
>>> d[a2] = 'a2'
>>> d
{<__main__.A instance at 0x8f2958c>: 'a1', <__main__.A instance at 0x8f2950c>: 'a2'}
如果想要让同一个类的任意两个实例都是哈希等价键,则可以参考以下示例:
>>> class A:
... def __hash__(self):
... return hash(A)
... def __cmp__(self, other):
... return cmp(self.__hash__(), other.__hash__())
...
>>> a1 = A()
>>> a2 = A()
>>> hash(a1), hash(a2)
(-1064346499, -1064346499)
>>> cmp(a1, a2)
0
>>> d = {}
>>> d[a1] = 'a1'
>>> d
{<__main__.A instance at 0x8f64a4c>: 'a1'}
>>> d[a2] = 'a2'
>>> d
{<__main__.A instance at 0x8f64a4c>: 'a2'}
类似地,如果想要让一个类的任意一个实例与整数1成为哈希等价键,则可以按照以下方式实现:
>>> class A:
... def __hash__(self):
... return 1
... def __cmp__(self, other):
... return cmp(self.__hash__(), other.__hash__())
...
>>> a = A()
>>> hash(1), hash(a)
(1, 1)
>>> cmp(1, a)
0
>>> d = {}
>>> d[1] = 'int 1'
>>> d
{1: 'int 1'}
>>> d[a] = 'instance a'
>>> d
{1: 'instance a'}
四、字典视图
从2.7版本开始,Python中引入了字典视图(Dictionary views)。字典视图 是字典的 动态视图:它们会与字典保持同步,实时反应出字典的变化。字典视图共有3种:键视图(Keys views)、值视图(Values views)和 元素视图(Items views),它们分别由dict.viewkeys()、dict.viewvalues()和dict.viewitems()三个函数返回。
所有的字典视图都支持以下操作:
操作 | 说明 |
---|---|
len(dictview) | 返回字典的长度 |
iter(dictview) | 返回(键、值、元素)迭代器 |
x in dictview | 判断x是否为(键、值、元素)的成员 |
此外,因为字典的键是 唯一 且 可哈希的,所以 键视图 还支持 类似集合(set-like)的操作。如果字典的值是 可哈希的,那么 元素视图 也支持这些操作:
操作 | 说明 |
---|---|
dictview & other | 求交集 |
dictview | other | 求并集 |
dictview - other | 求差集 |
dictview ^ other | 求对称差集 |
关于字典视图的示例,请参考 Dictionary view objects。
五、应用
1、模拟switch-case语句
以下是C中一个使用switch-case语句的示例:
int select(char c)
{
int num = -1;
switch (c)
{
case 'a':
num = 1;
break;
case 'b':
num = 2;
break;
case 'c':
num = 3;
break;
default:
num = 0;
break;
}
return num;
}
Python中没有提供switch-case语句,但使用字典可以轻松实现类似上面的功能:
d = {'a': 1, 'b': 2, 'c': 3}
# 普通版本
def select1(c):
num = -1
if c not in d:
num = 0
else:
num = d[c]
return num
# 惊呆版本
def select2(c):
return d.get(c, 0)
2、稀疏矩阵
使用元组作为字典的键,可以构建类似稀疏矩阵的数据结构:
>>> matrix = {}
>>> matrix[(2, 3, 4)] = 88
>>> matrix[(7, 8, 9)] = 99
>>>
>>> matrix
{(2, 3, 4): 88, (7, 8, 9): 99}
>>>
>>> x, y, z = 2, 3, 4
>>> matrix[(x, y, z)]
88
3、符号表
实际上,Python本身就在内部大量使用了字典,一个典型的应用就是符号表:
>>> locals() # 局部符号表
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
>>> globals() # 全局符号表
{'__builtins__': <module '__builtin__' (built-in)>, '__name__': '__main__', '__doc__': None, '__package__': None}
Python基础:映射(字典)的更多相关文章
- python基础之字典dict和集合set
作者:tongqingliu 转载请注明出处:http://www.cnblogs.com/liutongqing/p/7043642.html python基础之字典dict和集合set 字典dic ...
- Python基础数据类型-字典(dict)
Python基础数据类型-字典(dict) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 本篇博客使用的是Python3.6版本,以及以后分享的每一篇都是Python3.x版本的哟 ...
- python基础之字典、集合
一.字典(dictionary) 作用:存多个值,key-value存取,取值速度快 定义:key必须是不可变类型,value可以是任意类型 字典是一个无序的,可以修改的,元素呈键值对的形式,以逗号分 ...
- Python基础知识---字典
现在在实习期间,好久没用Python了,今天在做Java项目时用的HashMap让我联想到了Python中的字典,就写一些Python字典的知识吧,复习复习. 字典: key --> valu ...
- python基础5 字典
一.字典 字典是python的基础数据类型之一:字典可以存储大量的数据,关系型数据. 同样他也是python中唯一的映射类的数据类型. 数据类型的分类: 可变的(不可哈希)数据类型:list,dict ...
- Python基础__字典、集合、运算符
之前讨论的字符串.列表.元组都是有序对象,本节则重点讨论无序对象:字典与集合.一.字典 列表是Python中的有序集合,列表中的序指的是列表中的元素与自然数集形成了一个一一对应的关系.例如L=['I' ...
- python基础类型—字典
字典 字典是python中唯一的映射类型,采用键值对(key-value)的形式存储数据.python对key进行哈希函数运算,根据计算的结果决定value的存储地址,所以字典是无序存储的,且key必 ...
- python基础之字典以及增删改查
字典:字典是python中唯一的一个映射类型,主要形式为 dic = {key1:value,key2:value2,....} 字典中key的值是唯一的,主要关系到HASH算法,并且key的值必须是 ...
- Python基础系列----字典、基本语句
1.定义 映 ...
- python基础类型(字典:dict)
字典的介绍: 字典(dict)Python中唯一的一个映射类型.他是以{}括起来的键值对组成,在dict中key是唯一的.在保存的时候,根据key来计算出一个内存地址,然后将key-value保存到这 ...
随机推荐
- 根据第三方提供的wsdl报文(axis2开发),进行的webservice应用的开发实例
接口应用名称:NgCallService 入参和出参信息 入参和出参报文信息 入参: <?xml version="1.0" encoding="UTF-8&quo ...
- C变量类型和作用域
C语言中所有变量都有自己的作用域,申明变量的类型不同,其作用域也不同.C语言中的变量,按照作用域的范围可分为两种, 即局部变量和全局变量. 一.局部变量 局部变量也称为内部变量.局部变量是在函数内作定 ...
- 深入剖析 redis 主从复制
主从概述 redis 支持 master-slave(主从)模式,redis server 可以设置为另一个 redis server 的主机(从机),从机定期从主机拿数据.特殊的,一个 从机同样可以 ...
- 【WebMisCentral WMC】基于Extjs 4.2x的企业级用户授权认证中心系统(SSO+AM+SM),多租户SAAS应用
http://saas.chinacloudtech.com 题记 三年磨一剑,在企业信息化的道路上已经走了3年之久了,3年多时间里做了很多,突破了很多:有无奈和辛酸,也有收货与喜悦:自我价值也在不断 ...
- Swift基础--手势识别(双击、捏、旋转、拖动、划动、长按)
// // ViewController.swift // JieUITapGestureRecognizer // // Created by jiezhang on 14-10-4. // ...
- (笔记)Linux内核学习(八)之定时器和时间管理
一 内核中的时间观念 内核在硬件的帮助下计算和管理时间.硬件为内核提供一个系统定时器用以计算流逝的时间.系 统定时器以某种频率自行触发,产生时钟中断,进入内核时钟中断处理程序中进行处理. 墙上时间和系 ...
- Java IO 之 FileInputStream & FileOutputStream源码分析
Writer :BYSocket(泥沙砖瓦浆木匠) 微 博:BYSocket 豆 瓣:BYSocket FaceBook:BYSocket Twitter ...
- WPF国际化(多语言)
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.W ...
- 转载 ACM训练计划
leetcode代码 利用堆栈:http://oj.leetcode.com/problems/evaluate-reverse-polish-notation/http://oj.leetcode. ...
- SSAS:菜鸟摸门
官方:SSAS 多维模型 Analysis Services 多维解决方案使用多维数据集结构来分析多个维度之间的业务数据. 多维模式是 Analysis Services 的默认服务器模式. 它包括针 ...