6 - Python内置结构 - 字典
1 字典介绍
在Python中字典属于一种映射类型,它和set相同,同样属于非线性结构存储,Python官方对dict有如下解释
- 一个映射对象映射一个可hash的值到任意一个对象上去。
- 映射是可变的对象。
- dict是当前唯一一个标准的映射类型。
- 字典的键几乎可以任意的值。
- 字典的值可以不必可hash,也就是说值可以是列表,字典,或者其他任意可变的对象
- 如果key相同,那么后面的value将会覆盖先前的value
- 不建议使用float类型作为字典的key
简单来说:字典是由key:value键值对组成的数据的集合,它的主要特点是 可变的
、无序的
、不重复的
。
字典的key必须是可hash对象。
2 字典的基本操作
字典是除set集合以外另一种可变的非线性容器模型,在Python中非常强大,适合各种结构数据的存储、嵌套等。
2.1 字典的定义
字典的每个key到value的键值对用冒号(:)分割,每对之间用逗号(,)分割,整个字典包括在花括号({})中。例:{'a':1, 'b':2}
,Python提供了多种创建字典的方式,如下:
- 基本格式:
d = dict()
或者d = {}
dict(**kwargs)
: 使用name=value对,来初始化一个字典dict(iterable, **kwargs)
:使用可迭代对象和name=value构造字典,注意可迭代对象必须是一个二元结构
dict(mapping, **kwargs)
: 使用一个字典构造另一个字典dic = {'a':1, 'b':2, 'c':3, 'd':[1,2,3]}
dic = dict.fromkeys(iterable, value)
: 使用可迭代对象的值作为key生成字典,value默认为0,否则用指定的value对字典进行初始化。
In [114]: d1=dict()
In [115]: d2={}
In [118]: d3 = dict(a=1,b=2)
In [120]: d3
Out[120]: {'a': 1, 'b': 2}
In [124]: d4 = dict([('a',1),('b',2)], c=3, d=4)
In [125]: d5 = dict(d4,e=5,f=6)
In [126]: d7 = dict.fromkeys(range(5))
In [127]: d8 = dict.fromkeys(range(5),100)
In [128]: d7
Out[128]: {0: None, 1: None, 2: None, 3: None, 4: None}
In [131]: d8
Out[131]: {0: 100, 1: 100, 2: 100, 3: 100, 4: 100}
2.2 字典元素的访问
有如下三种方式访问字典的键值对:
d[key]
: 返回key对应的value,key不存在抛出KeyError异常dict.get(key[, default])
: 返回key对应的value,key不存在返回缺省值,如果没有设置缺省值赶回Nonedict.setdefault(key[, default])
: 返回key对应的值value,key不存在,添加key:value键值对(value设置为default),并返回value,如果default没有设置缺省为None
In [32]: dic = {'a':1, 'b':2, 'c':3, 'd':4}
In [33]: dic['a']
Out[33]: 1
In [34]: dic['e'] # 不存在'e'这个key,所以直接访问会出现异常
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-34-87d22c709971> in <module>
----> 1 dic['e']
KeyError: 'e'
In [35]: dic.get('a') # key存在,则返回对应的值
Out[35]: 1
In [36]: dic.get('e') # 不存在,默认会返回None,ipython优化了None的输出,所以这里无显示
In [37]: dic.get('e','not exist') # 不存在时,由指定的default进行返回
Out[37]: 'not exist'
In [38]: dic.setdefault('a', 'ok?') # 设置a的值为ok?,a存在,所以返回a对应的值1
Out[38]: 1
In [39]: dic.setdefault('e', 'ok?') # 设置e的值为ok?,e不存在,所以设置并放回value(key不存在时等同于设置并访问了)
Out[39]: 'ok?'
In [40]: dic
Out[40]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
当然字典也可以被迭代访问,后面介绍
2.3 字典的增删改
由于字典可变、非线性、无序的特性,而且字典的key必须是可hash的对象,查找某个key也是直接hash(),然后找到对应的房间的,所以我们对它某个key的修改可以理解为是O(1)
的操作,效率很高,主要有以下几种方法。
d[key] = value
: 将key对应的值修改为value,key不存在添加新的key:value对。dic.update([other]) --> None
: 使用另一个字典的k,v对更新本字典,key不存在时添加,存在时则覆盖,所以不会返回新的字典,属于原地修改。dic.pop(key[, default])
: key存在,移除它,并返回它的value,key不存在返回指定的default,如果default未指定,那么会返回KeyError异常。dic.popitem()
: 移除并返回一个任意的键值对,字典为empty时,抛出KeyError异常。dic.clear()
: 清空字典。del dic['a']
: 通用的删除变量方法。
In [41]: dic
Out[41]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
In [42]: dic['a'] = 1000
In [43]: dic
Out[43]: {'a': 1000, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
In [44]: dic2 = {'a':200,'f':50}
In [45]: dic.update(dic2)
In [46]: dic
Out[46]: {'a': 200, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?', 'f': 50}
In [48]: dic.pop('a') # 弹出一个key'a',key存在返回key对应的value
Out[48]: 200
In [49]: dic.pop('g') # 弹出一个key'g',key不存在,又没有指定default,则会报KeyError异常
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-49-311c3ba80251> in <module>
----> 1 dic.pop('g')
KeyError: 'g'
In [50]: dic.pop('g','not exist') # 指定了default,当key不存在时,会返回指定的default值
Out[50]: 'not exist'
In [51]: dic.popitem() # 弹出一个key:valyue键值对,返回对象是元组形式
Out[51]: ('d', 4)
In [52]: dic
Out[52]: {'b': 2, 'c': 3, 'e': 'ok?', 'f': 50}
In [53]: del dic['e']
In [54]: dic
Out[54]: {'b': 2, 'c': 3, 'f': 50}
In [55]: dic.clear()
In [56]: dic
Out[56]: {}
当我们以字典的某个对象比如keys,values,items等为条件对字典进行遍历时,我们不能在遍历的同时删除字典的元素,字典在运行时不允许长度改变,但是在list中这种操作是可以的,但是会得到意想不到的结果,建议对容器进行遍历的同时不要修改它的长度。
In [7]: s
Out[7]: {'a': 1, 'b': 2, 'c': 4, 'd': 5, 'e': 7, 'j': 10}
In [8]: len(s)
Out[8]: 6
In [10]: for i in range(6):
...: s.popitem()
...:
In [11]: s
Out[11]: {}
# 下面这种方式是错的,也是觉得不可以的。
for i in s.keys():
s.pop(i)
3 字典遍历
在Python中,我们所说的基本数据结构:字符串、元组、列表,集合,包括字典,都可以认为是一个容器箱子,只要是容器,我们就可以进行遍历(是否有序和是否可以遍历没有必然关系,只不过有序的话是顺序拿出,而无序则是随机拿出),我们可以使用多种方式对字典进行迭代遍历,但是有些地方和其他类型不同。
3.1 遍历字典的key
dic.keys()
: --> dict_keys
--> 返回字典dic的所有key组成的一个dict_keys视图集合(类set结构,不会生成新的内存空间
)。
In [64]: dic = {'a':1, 'b':2, 'c':3, 'd':4}
In [65]: for key in dic:
...: print(key)
a
d
c
b
In [66]: for key in dic.keys():
...: print(key)
a
d
c
b
In [67]: dic.keys()
Out[67]: dict_keys(['a', 'd', 'c', 'b'])
迭代字典就是在迭代字典的key,所以直接迭代字典和使用字典的keys()方法返回一个keys的视图然后再迭代,是一样的效果。
3.2 遍历字典的value
dic.values()
: --> dict_values
--> 返回字典dic的所有values组成的一个dict_values视图集合(类set结构,不会生成新的内存空间
)。
In [69]: for i in dic:
...: print(dic[i])
1
4
3
2
In [70]: for i in dic.values():
...: print(i)
1
4
3
2
In [71]: dic.values()
Out[71]: dict_values([1, 4, 3, 2])
可以首先遍历字典的key,然后再通过key来访问对应的value,也可以通过values()直接访问values。
3.3 变量字典的键值对
dic.items()
: --> dict_items
--> 返回字典dic的所有的key和value(每个key和value的键值对由元组表示)组成的一个dict_items视图集合(类set结构,不会生成新的内存空间
)。
In [75]: for i in dic.items():
...: print(i)
...:
('a', 1)
('d', 4)
('c', 3)
('b', 2)
In [77]: for key,value in dic.items():
...: print('key:{} value:{}'.format(key,value))
...:
key:a value:1
key:d value:4
key:c value:3
key:b value:2
In [78]:
由于返回的每个键值对为元组格式,那么利用我们前面学的封装与结构,可以很方便的获取key和它对应的value
3.4 字典遍历小结
在Python3中,keys、values、items方法返回一个类似一个生成器的可迭代对象,不会把函数的返回结果复制到内存空间中。
- Dictionary view对象,可以使用len()、iter()、in
操作 - 字典的entry的动态视图,字典变化,视图将反映出这些变化
- keys返回一个类似set的对象,也可以看作是一个set集合,如果values可hash的话,那么items也可以看作是类set对象
Python 2中,keys、values、items方法会返回一个新的列表,占据新的内存空间,所以Python 2建议使用iterkeys、itervalues、iteritems,返回一个迭代器,而不是返回一个copy
[11:20:32 python@centos7 ~]$python
Python 2.7.5 (default, Oct 30 2018, 23:45:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = {'a':1,'b':2}
>>> s.keys() # 直接生成一个keys的列表
['a', 'b']
>>> s.iterkeys() # 对象,迭代可以获取数据
<dictionary-keyiterator object at 0x7f271c5fa520>
>>>
4 defaultdict默认值字典
defaultdit object是dict的子类,我们称它为默认值字典,即在创建字典时给所有的value指定一个默认值,它存放在collections模块中,使用前需要先进行导入。为什么有默认值字典这种类型呢?那么请看如下代码:
dic = {}
for i in 'abacdabeddfef':
if i not in dic: # 这句其实也可以优化为 dic[i] = dic.get(i, 0) + 1
dic[i] = 0
dic[i] += 1
print(dic)
我们在计算一个字符串或者一个列表中的元素重复的次数时,通常会用到字典对齐进行计数,如果元素不存在字典中,那么就需要初始化元素,当我们使用默认值字典时,就可以优化的更简洁。
from collections import defaultdict
dic = defaultdict(int) # defaultdict(lambda :0) 这种方法也可以设置默认为0
for i in 'abacdabeddfef':
dic[i] += 1 # 默认是int型,可以直接加减
print(dic)
5 OrdereDict有序字典
Ordered dictionaries像一个有序字典,但是它记住的是插入元素的顺序。当我们迭代有序字典时,它会按照这些键值对插入的顺序返回。它同样存在于collections模块中,需要使用是请首先导入。
In [1]: from collections import OrderedDict
In [2]: dic = OrderedDict()
In [5]: dic = dic.fromkeys('abc',1)
In [6]: dic
Out[6]: OrderedDict([('a', 1), ('b', 1), ('c', 1)])
In [8]: for k,v in dic.items(): # 按照插入的顺序
...: print(k,v)
...:
a 1
b 1
c 1
In [10]: dic = dict([('a', 1), ('b', 1), ('c', 1)])
In [11]: for k,v in dic.items(): # 无序的
...: print(k,v)
...:
a 1
c 1
b 1
In [12]:
注意:在3.6的版本的python在python/ipython解释器中,直接迭代或者打印时,是有序的(OrderedDict),但是在3.5版本以前都是随机的,千万不要以为字典是有序的!
6 - Python内置结构 - 字典的更多相关文章
- Python内置字典;dict ,set
dict and set dict: 键-值 /重复添加 set : 键 / key不能重复 对于不变对象来说,调用对象自身的任意方法,也不会改变该对象自身的内容.相反,这些方法会创建新的对象并返 ...
- 浅谈Python内置对象类型——数字篇(附py2和py3的区别之一)
Python是一门面向对象的编程设计语言,程序中每一样东西都可以视为一个对象.Python内置对象可以分为简单类型和容器类型,简单类型主要是数值型数据,而容器类型是可以包含其他对象类型的集体,如序列. ...
- 一篇文章掌握 Python 内置 zip() 的全部内容
一篇文章掌握 Python 内置 zip() 的全部内容 zip() 是 Python 中最好用的内置类型之一,它可以接收多个可迭代对象参数,再返回一个迭代器,可以把不同可迭代对象的元素组合起来. 我 ...
- python内置函数
python内置函数 官方文档:点击 在这里我只列举一些常见的内置函数用法 1.abs()[求数字的绝对值] >>> abs(-13) 13 2.all() 判断所有集合元素都为真的 ...
- python 内置函数和函数装饰器
python内置函数 1.数学相关 abs(x) 取x绝对值 divmode(x,y) 取x除以y的商和余数,常用做分页,返回商和余数组成一个元组 pow(x,y[,z]) 取x的y次方 ,等同于x ...
- Python 内置函数笔记
其中有几个方法没怎么用过, 所以没整理到 Python内置函数 abs(a) 返回a的绝对值.该参数可以是整数或浮点数.如果参数是一个复数,则返回其大小 all(a) 如果元组.列表里面的所有元素都非 ...
- 【转】python 内置函数总结(大部分)
[转]python 内置函数总结(大部分) python 内置函数大讲堂 python全栈开发,内置函数 1. 内置函数 python的内置函数截止到python版本3.6.2,现在python一共为 ...
- 【转】Python 内置函数 locals() 和globals()
Python 内置函数 locals() 和globals() 转自: https://blog.csdn.net/sxingming/article/details/52061630 1>这两 ...
- python内置函数,匿名函数
一.匿名函数 匿名函数:为了解决那些功能很简单的需求而设计的一句话函数 def calc(n): return n**n print(calc(10)) #换成匿名函数 calc = lambda n ...
随机推荐
- SpringMVC 应知应会
springMVC 是表现层技术,可以用来代替 struts2,下面是简略图:主要是处理器和视图,只有这两个部分需要编写代码. springMVC 三大组件:处理器映射器,处理器适配器,视图解析器. ...
- Debugger DataSet 调试时查看DataSet
delphi 跟踪调试的时候查看DataSet数据记录 Ctrl+F7调试 增强工具DataSethttp://edn.embarcadero.com/article/40268 http://do ...
- BZOJ 1226 学校食堂(状压DP)
状压DP f(i,j,k)表示前i−1个人已经吃了饭,且在i之后的状态为j的人也吃了饭(用二进制表示后面的状态),最后吃的那个人是i之后的第k个 (注意k可以是负数) 然后 如果j&1=1那么 ...
- Infinity NaN undefined和null
Infinity属性用于存放表示正无穷大的数值. 负无穷大是表示负无穷大一个数字值. 该属性为Global对象的一个只读属性, 所有主流浏览器均支持该属性. Infinity属性的值为Number类型 ...
- OpenFlow 消息
消息类型 OpenFlow 的消息共分为三类: Controller-to-Switch 顾名思义,此类消息是由控制器主动发出 Features 用于获取交换机特性 Configuration 用于配 ...
- Linux网络接口配置文件解析
[root@localhost ~]# cat /etc/sysconfig/network-scripts/ifcfg-eth0# Intel Corporation 82545EM Gigabit ...
- Asp.Net保存session的三种方法 (Dll文件更新导致session丢失的解决办法)
1. InProc模式(默认值):asp.net将session保存到当前进程中,这种方式最快,但是不能多台服务器共享session,且会话状态数据容易丢失. <sessionState mod ...
- [JSOI2007]建筑抢修——贪心反悔堆
题目描述 小刚在玩JSOI提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T部落消灭了所有z部落的入侵者.但是T部落的基地里已经有N个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建 ...
- javaWeb中,文件上传和下载
在Web应用系统开发中,文件上传和下载功能是非常常用的功能,今天来讲一下JavaWeb中的文件上传和下载功能的实现. 对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用 ...
- Android开发-eclipse+phonegap(Cordova)环境搭建
搭建步骤: 一.安装java [官网下载].eclipse+ADT+Android SDK [点我下载x86(android-22)] | [adt-bundle-windows-x86_64-201 ...