字典(当索引不好用时)
列表这种数据结构适合于将值组织到一个结构中,并且通过编号对其进行引用。在本节中,将介绍一种通过名字引用值得数据结构。这种类型的数据结构称为映射(mapping)。字典是Python中唯一内建的映射类型。字典中的值并没有特殊的顺序,但都是存储在一个特定的键(key)下。键可以是数字、字符串甚至是元组。
字典
字典的特性:
dict是无序的
key是唯一的,故天生去重
注意:字典中的键是唯一(其他类型的映射也如此),而值并不唯一。
查询速度快,比列表快多了
为什么会查询速度会快呢?因为他是hash类型的,那什么是hash呢?
哈希算法将任意长度的二进制值映射为较短的固定长度的二进制值,这个小的二进制值称为哈希值。哈希值是一段数据唯一且极其紧凑的数值表示形式。如果散列一段明文而且哪怕只更改该段落的一个字母,随后的哈希都将产生不同的值。要找到散列为同一个值的两个不同的输入,在计算上是不可能的,所以数据的哈希值可以检验数据的完整性。一般用于快速查找和加密算法
dict会把所有的key变成hash 表,然后将这个表进行排序,这样,你通过data[key]去查data字典中一个key的时候,python会先把这个key hash成一个数字,然后拿这个数字到hash表中看没有这个数字, 如果有,拿到这个key在hash表中的索引,拿到这个索引去与此key对应的value的内存地址那取值就可以了。
创建和使用字典
创建一个字典
>>> student={"name":"Mike",'age':23} >>> student {'age': 23, 'name': 'Mike'}
也可以用dict函数,通过其他映射(比如其他字典)或者(键,值)对的序列建立字典:
>>> items=[('name','Mike'),('age',42)] >>> d=dict(items) >>> d {'age': 42, 'name': 'Mike'}
dict函数也可以通过关键字参数来创建字典:
>>> d=dict(name='Mike',age=23) >>> d {'age': 23, 'name': 'Mike'}
基本字典操作
字典的基本操作在很多方面与序列(sequence)类似:
方法 | 说明 |
len(d) | 返回d中项的数量(键值对) |
d[k] | 返回关联到键k上的值 |
d[k]=v | 将值v关联到键k上 |
del d[k] | 删除键为k的项 |
k in d |
检查d中是否含有键为k的项 |
注意:在字典中检查键的成员资格比在列表中检查值的成员资格更高效,数据结构规模越大,两者的效率差距越明显。
字典的格式化字符串:
在每个转换说明符(conversion specifier)中的%字符后面,可以加上键(用圆括号括起来),后面再跟上其他说明元素:
>>> info={'name':'Mike','age':23,'job':'IT','salary':10000} >>> "%(name)s is %(age)s and his job is %(job)s."%info 'Mike is 23 and his job is IT.'
字典方法
增:
>>> info {'job': 'IT', 'name': 'Mike', 'salary': 10000} >>> info['address']='广东' >>> info {'job': 'IT', 'name': 'Mike', 'salary': 10000, 'address': '广东'}
改:
{'job': 'IT', 'name': 'Mike', 'salary': 10000, 'address': '广东'} >>> info['salary']=12000 >>> info {'job': 'IT', 'name': 'Mike', 'salary': 12000, 'address': '广东'}
clear:
clear方法清除字典中所有的项。这是个原地操作(类似于list.sort),所以无返回值(或者返回值为None)
>>> info {'age': 23, 'job': 'IT', 'name': 'Mike', 'salary': 10000} >>> returned_value=info.clear() >>> info {} >>> print(returned_value) None
fromkeys:
fromkeys方法使用给定的键建立新的字典,每个键都对应一个默认的值None。
>>> {}.fromkeys(['name','age']) {'age': None, 'name': None} #通过dict方法 >>> dict.fromkeys(['job','salary']) {'job': None, 'salary': None} #自定义初始value >>> dict.fromkeys(['job','salary'],'(unknow)') {'job': '(unknow)', 'salary': '(unknow)'}
查:(get方法)
一般来说,如果试图访问字典中不存在的项是会报错,get方法是个更宽松的访问字典项的方法,当使用get方法访问一个不存在的键时,没有任何异常,而得到None值,还可以自定义“默认”值,替换None:
#不用get >>> info={'name':'Mike','age':23,'job':'IT','salary':10000} >>> info['address'] Traceback (most recent call last): File "<pyshell#40>", line 1, in <module> info['address'] KeyError: 'address' #使用get >>> info.get('name') 'Mike' >>> print(info.get('address')) None >>> print(info.get('address','不存在')) 不存在
items
items方法将字典所有的项以列表方式返回,列表中的每一项都表示为(键,值)对的形式,但是项的返回时并没有遵循特定的次序:
>>> info {'age': 23, 'job': 'IT', 'name': 'Mike', 'salary': 10000} >>> info.items() dict_items([('age', 23), ('job', 'IT'), ('name', 'Mike'), ('salary', 10000)])
keys:keys方法将字典中的键一列表的形式返回:
>>> info {'age': 23, 'job': 'IT', 'name': 'Mike', 'salary': 10000} >>> info.keys() dict_keys(['age', 'job', 'name', 'salary'])
values:一列表的形式返回字典中的值,返回值的列表中可以包含重复的元素
删:(pop、popitem、del)
pop方法用来获得对应于给定键的值,然后将这个键-值对从字典删除:
>>> info {'age': 23, 'job': 'IT', 'name': 'Mike', 'salary': 10000} >>> info.pop('salary') 10000 >>> info {'age': 23, 'job': 'IT', 'name': 'Mike'}
popitem方法(随机删)类似于list.pop,后者会弹出列表的最后一个元素。但不同的是,popitem弹出随机的项,因为字典是无序的。(该方法用首先获取键的列表)
>>> info {'age': 23, 'job': 'IT', 'name': 'Mike'} >>> info.popitem() ('age', 23) >>> info {'job': 'IT', 'name': 'Mike'}
setdefault:
setdefault方法在某种程度上类似于get方法,能够获得与给定值相关联的值,除此之外,setdefault还能在字典中不含有给定键的情况下设定相应的键值。
>>> d={} >>> d.setdefault('name','待定') '待定' >>> d {'name': '待定'} >>> d['name']='Jack' >>> d {'name': 'Jack'}
update:
update方法可以利用一个字典更新另一个字典:
>>> info {'job': 'IT', 'name': 'Mike', 'salary': 8000} >>> new_salary={'salary':10000} >>> info.update(new_salary) >>> info {'job': 'IT', 'name': 'Mike', 'salary': 10000}
提供的字典中的项会被添加到旧的字典只能怪,若有相同的键则会覆盖。update方法可以使用与调用dict函数(或者类型构造函数)同样的方式进行调用。这就意味着update可以和映射、拥有(键,值)对的队列(以及其他可迭代对象)以及关键字参数一起调用。
遍历字典:
>>> dict={ 'name':'Mike', 'age':'18', 'sex':"男", } >>> for i in dict: #高效 print(i,dict[i]) sex 男 age 18 name Mike #低效 items会把先字典变成一个列表,当数据量很大时,转换的时间自然就拉长了 >>> for i, v in dict.items(): print( i , v) sex 男 age 18 name Mike