Python基础:04映射类型
字典是Python语言中唯一的映射类型。一个字典对象是可变的,它是一个容器类型,能存储任意个数的Python对象。字典中的数据是无序排列的。
映射类型也可被称做哈希表,哈希表的算法是获取键,对键执行一个叫做哈希函数的操作,并根据计算的结果,选择在数据结构的某个地址中来存储值。任何一个值存储的地址皆取决于它的键。正因为这种随意性,哈希表中的值是没有顺序的。哈希表一般有很好的性能,因为用键查询相当快。
一:创建字典
1:dict()
从Python2.2版本起,可以用工厂方法 dict() 来创建字典。
如果不提供参数,会生成空字典。若参数是可以迭代的,如序列、迭代器,或是一个支持迭代的对象,那每个可迭代的元素必须成对出现。在每个值对中,第一个元素是字典的键、第二个元素是字典中的值。例子:
>>> fdict = dict((['x', 1], ['y', 2]))
>>> fdict
{'y': 2, 'x': 1} >>> dict(zip(('x', 'y'), (1, 2)))
{'y': 2, 'x': 1} >>> dict([('xy'[i-1], i) for i in range(1,3)])
{'y': 2, 'x': 1}
如果输入参数是(另)一个映射对象,比如,一个字典对象,对其调用dict()会从存在的字典里复制内容来生成新的字典。新生成的字典是原来字典对象的浅复制版本, 它与用字典的内建方法copy() 生成的字典对象是一样的。但是copy()更快,所以推荐使用copy()。
从Python2.3 开始,dict()方法可以接受关键字参数字典:
>>> dict(x=1, y=2)
{'y': 2, 'x': 1}
2:fromkeys()
从Python2.3 版本起, 可以用内建方法fromkeys()来创建一个"默认"字典,字典中元素具有相同的值 (如果没有给出, 默认为None):
>>> ddict = {}.fromkeys(('x', 'y'), -1)
>>> ddict
{'y': -1, 'x': -1} >>> edict = {}.fromkeys(('foo', 'bar'))
>>> edict
{'foo': None, 'bar':None}
二:访问字典
从Python2.2 开始,可以不必再用keys()方法获取供循环使用的键值列表了。 可以用迭代器来轻松地访问类序列对象(sequence-like objects),比如字典和文件。只需要用字典的名字就可以在 for 循环里遍历字典。
>>> dict2 = {'name': 'earth', 'port': 80}
>>>> for key in dict2:
... print 'key=%s, value=%s' % (key, dict2[key])
... key=name, value=earth
key=port, value=80
要得到字典中某个元素的值, 可以用字典的键查找操作符([ ]):
>>> dict2['name']
'earth'
使用[ ]时,如果在这个字典中没有对应的键,将会产生一个错误:
>>> dict2['server']
Traceback (innermost last):
File "<stdin>", line 1, in ?
KeyError: server
检查一个字典中是否有某个键,是用字典的 has_key()方法, 或者另一种比较好的方法就是从2.2 版本起用的,in 或 not in 操作符。
三:更新和删除字典
1:更新
字典的键查找操作符([ ]),既可以用于从字典中取值,也可以用于给字典赋值。如果字典中该键已经存在,则字典中该键对应的值将被新值替代。如果改键不存在,则相当于增加新条目:
>>> dict2['name'] = 'venus' # 更新已有条目
>>> dict2['arch'] = 'sunos5' # 增加新条目
2:删除
以下是删除字典和字典元素的例子:
del dict2['name'] # 删除键为“name”的条目
dict2.clear() # 删除dict2 中所有的条目
del dict2 #删除整个dict2 字典
dict2.pop('name') #删除并返回键为“name”的条目
四:字典的比较
字典的比较不是很有用也不常见。比较算法按照以下的顺序:
(1)比较字典长度
如果字典的长度不同,那么用cmp(dict1, dict2) 比较大小时,如果字典 dict1 比 dict2 长,cmp()返回正值,如果 dict2 比 dict1 长,则返回负值。也就是说,字典中的键的个数越多,这个字典就越大。
(2)比较字典的键
如果两个字典的长度相同,那就按字典的键比较;键比较的顺序和 keys()方法返回键的顺序相同。这时,如果两个字典的键不匹配时,对这两个(不匹配的键)直接进行比较。当dict1 中第一个不同的键大于dict2 中第一个不同的键,cmp()会返回正值。
(3)比较字典的值
如果两个字典的长度相同而且它们的键也完全匹配,则用字典中每个相同的键所对应的值进行比较。一旦出现不匹配的值,就对这两个值进行直接比较。若dict1 比dict2 中相同的键所对应的值大,cmp()会返回正值。
(4) 完全匹配
到此为止,每个字典有相同的长度、相同的键、每个键也对应相同的值,则字典完全匹配,cmp函数返回0 值。
五:字典的键
大多数Python对象都可以作为键;但它们必须是可哈希的对象。所有不可变的类型都是可哈希的,因此它们都可以做为字典的键。像列表和字典这样的可变类型,由于它们不是可哈希的,所以不能作为键。
在执行中字典中的键不允许被改变。比如创建了一个字典,字典中包含一个元素(一个键和一个值)。可能是由于某个变量的改变导致键发生了改变。这时候你如果用原来的键来取出字典里的数据,会得到KeyError。现在你没办法从字典中获取该值了,因为键本身的值发生了变化。由于上面的原因,字典中的键必须是可哈希的, 所以数字和字符串可以作为字典中的键, 但是列表和其他字典不行。
一个要说明的是问题是数字:值相等的数字表示相同的键。换句话来说,整型数字 1 和 浮点数 1.0 的哈希值是相同的,即它们是相同的键。
也有一些可变对象(很少)是可哈希的,它们可以做字典的键,但很少见。举一个例子,一个实现了__hash__() 特殊方法的类。因为__hash__()方法返回一个整数,所以仍然是用不可变的值(做字典的键)。
数字和字符串可以被用做字典的键,元组虽然是不可变的,但是元组也有可能包含可变对象。所以用元组做有效的键,必须要加限制:元组中只包括像数字和字符串这样的不可变参数,才可以作为字典中有效的键。
六:映射类型相关函数
内建函数hash()可以判断某个对象是否可以做一个字典的键。将一个对象作为参数传递给 hash(), 会返回这个对象的哈希值。 只有这个对象是可哈希的,才可作为字典的键 (函数的返回值是整数,不产生错误或异常)。
如果非可哈希类型作为参数传递给hash()方法,会产生TypeError 错误(因此,如果使用这样的对象作为键给字典赋值时会出错):
>>> hash([])
Traceback (innermost last): File"<stdin>", line 1, in ?
TypeError: list objects are unhashable
>>>
>>> dict2[{}] = 'foo'
Traceback (most recent call last): File"<stdin>", line 1, in ?
TypeError: dict objects are unhashable
七:映射类型内建方法
1:keys()方法,返回一个列表,包含字典中所有的键(的副本)。
2:values()方法,返回一个列表,包含字典中所有的值(的副本)。
3:items(),返回一个包含所有(键, 值)元组(的副本)的列表。这些方法在不按任何顺序遍历字典的键或值时很有用。
>>> dict2.keys()
['port', 'name'] >>> dict2.values()
[80, 'earth'] >>> dict2.items()
[('port', 80), ('name', 'earth')]
4:dict.get(key, default=None)
对字典dict中的键key,返回它对应的值value,如果字典中不存在此键,则返回default的值,参数default的默认值为None,所以该函数不会引发KeyError异常。该函数也不会改变字典。
5:dict.pop(key [, default])
如果字典中key键存在,删除并返回dict[key],如果key 键不存在,但是给出了default参数,则返回default。如果没有给出default且key不存在,则引发KeyError 异常。该函数有可能改变字典。
6:update()方法可以用来将一个字典的内容添加到另外一个字典中。字典中原有的键如果与新添加的键重复,那么重复键所对应的原有条目的值将被新键所对应的值所覆盖。原来不存在的条目则被添加到字典中。
7:clear()方法可以用来删除字典中的所有的条目。
>>> dict2= {'host':'earth', 'port':80}
>>> dict3= {'host':'venus', 'server':'http'}
>>> dict2.update(dict3)
>>> dict2
{'server': 'http', 'port': 80, 'host': 'venus'}
>>> dict3.clear()
>>> dict3
{}
8:copy()方法返回一个字典的副本。注意这只是浅复制。
9:setdefault(key [,default])是自2.0才有的内建方法, 使得代码更加简洁。它实现了常用的语法:如果字典中key存在,则不改变字典,直接返回它的值。如果所找的key在字典中不存在,则给这个键赋default并返回default,default默认为None。
>>> myDict = {'host': 'earth', 'port': 80}
>>> myDict.setdefault('port', 8080)
80 >>> myDict.setdefault('prot', 'tcp')
'tcp' >>> myDict.items()
[('prot', 'tcp'), ('host', 'earth'), ('port', 80)]
10:因keys(),items(), 和 values()方法的返回值都是列表。数据集如果很大会导致很难处理,因此iteritems(), iterkeys(), 和itervalues() 方法被添加到 Python2.2 中。这些函数与返回列表的对应方法相似,只是它们返回惰性赋值的迭代器,所以节省内存。
八:其他
要避免使用内建对象名字作为变量的标识符。不要用 dict, list, file, bool, str, input, len 这样的内建类型为变量命名。
>>> print 'host %(name)s is runningon port %(port)d' %dict2
host venus is running on port 6969
上面的print语句展示了另一种使用字符串格式符( %)的方法。用字典参数可以简化print 语句,因为这样做你只须用到一次该字典的名字,而不用在每个元素出现的时候都用元组参数表示。
Python基础:04映射类型的更多相关文章
- python基础之序列类型的方法——字符串方法
python基础之序列类型的方法--字符串方法 Hello大家好,我是python学习者小杨同学,经过一段时间的沉淀(其实是偷懒不想更新),我终于想起了自己的博客账号,所以这次带来的是序列方法的后半部 ...
- python基础之数值类型与序列类型
Hello大家好,我是python学习者小杨同学,已经学习python有一段时间,今天将之前学习过的内容整理一番,在这与大家分享与交流,现在开始我们的python基础知识之旅吧. 数值类型与序列类型 ...
- Python基础:映射(字典)
一.概述 映射类型(Mapping Types)是一种关联式的容器类型,它存储了对象与对象之间的映射关系. 字典(dict)是Python中唯一的映射类型,它是存储了一个个 键值对(由 键 映射到 值 ...
- Python标准库映射类型与可散列数据类型的关系
这里有两个概念似懂非懂,在这里明确一下: 映射类型: Python>3.2中,collections.abc模块有Mapping和MutableMapping两个抽象基类(Python2.6~3 ...
- python基础:映射和集合类型
python字典的迭代器遍历 字典有一个方法可以返回该字典的迭代器,这个方法就是: dict. iteritems() 当在字典中增加或者删除字典entry的时候,迭代器会失效的,类似于C++的stl ...
- Python基础4--数据类型
一.数据类型是什么鬼? 计算机顾名思义就是可以做数学计算的机器,因此,计算机程序理所当然地可以处理各种数值.但是,计算机能处理的远不止数值,还可以处理文本.图形.音频.视频.网页等各种各样的数据,不同 ...
- Python基础—02-数据类型
数据类型 存储单位 最小单位是bit,表示二进制的0或1,一般写作b 最小的存储单位是字节,用byte表示,1B = 8b 1024B = 1KB 1024KB = 1MB 1024MB = 1GB ...
- 1.8 Python基础知识 - 数值类型
一.int类型(任意精度整数) 整型类型(int)是表示整数的数据类型.与其他计算机语言有精度限制不同,Python的整数位数可以为任意长度位数(只受限制于计算机内存) 数字字符串即整型常量. pyt ...
- Python基础笔记_Number类型
import random import math import operator # 数字 # # 1. Python math 模块.cmath 模块 ''' Python math 模块.cma ...
随机推荐
- loj6229 这是一道简单的数学题
https://loj.ac/problem/6229 题解:https://blog.csdn.net/Vectorxj/article/details/79094659 套路推式子,杜教筛,证明复 ...
- 前端小知识--区分get和post请求
get和post是HTTP协议中的两种发送请求的方法. 如果你还不了解http,可以点击[HTTP协议①介绍](https://www.jianshu.com/p/632b890b75ac)[HTTP ...
- Tomcate 启动异常,java.net.BindException: Address already in use: JVM_Bind:80的解决办法
一直用Tomcat,但是前几天突然报错: java.net.BindException: Address already in use: JVM_Bind:80 第一反应就是80端 ...
- linux性能监视工具sar
sar是一个优秀的一般性能监视工具,它可以输出Linux所完成的几乎所有工作的数据.sar命令在sysetat rpm中提供.示例中使用sysstat版本5.0.5,这是稳定的最新版本之一.关于版本和 ...
- Hibernate_条件查询客户列表
分析:通过名称查询 实现: 1.在list.jsp中修改 2.修改ListCustomerServlet 首先获取cust_name,增加条件:若不为空,则模糊搜索,再调用Service方法,结果放到 ...
- 发布Qt Widgets桌面应用程序的方法
Qt是一款优秀的跨平台开发框架,它可以在桌面.移动平台以及嵌入式平台上运行.目前Qt 5介绍程序发布的文章帖子比较少.大家又非常想要知道如何发布Qt应用程序,于是我花了一点儿时间介绍一下如何发布Qt桌 ...
- setStorage、getStorage、 removeStorage 封装
// 本地存储 setStorage(name, data){ let dataType = typeof data; // json对象 if(dataType === 'object'){ win ...
- python中接受任意关键字的参数
1.*args args是非关键字参数,可以理解为形参,为了方便记忆我理解它是arguments的缩写. 2.*kwargs kwargs是键值对参数,为了方便记忆我理解它是key word argu ...
- springboot-mybatis双数据源配置
yml文件 spring: datasource: test1: driverClassName: com.mysql.jdbc.Driver url: jdbc:mysql://localhost: ...
- oracle国家字符集
国家字符集是一个备用字符集,利用此字符集可以在没有Unicode 数据库字符集的数据库中存储 Unicode 字符. 选择国家字符集的其它原因如下: 对于频繁的字符处理操作,不同的字符编码方案可能更为 ...