字典的定义
字典包括一系列的索引,不过就已经不叫索引了,而是叫键,然后还对应着一个值,叫键值。每个键对应着各自的一个单独的键值。这种键和键值的对应关系也叫键值对,有时候也叫项。其中,“键:值”元素的无序可变序列,字典中的每个元素包括“键”和“值”两部分,表示一种映射或对应关系,也称为关联数组。定义字典时,每个元素的“键”和“值”用冒号分隔,不同元素之间用逗号分隔,所有的元素放在一对大括号中。字典就像是一个列表一样,但更加泛化了,是列表概念的推广。在列表里面,索引必须是整数;而在字典里面,你可以用几乎任何类型来做索引了。用数学语言来说,一个字典就代表了从键到键值的一种映射关系,所以你也可以说每个键映射到一个键值。举例来说,我们可以建立一个从英语单词映射到西班牙语单词的字典,这样键和简直就都是字符串了。
建立字典
使用dict()函数
dict这个函数创建一个没有项目的空字典,如下所示:
>>> eng2sp = dict()
>>> eng2sp
{}
其中,大括号代表了一个空字典,要在字典里添加项(项是指字典的键与值的对应关系,也叫键值对),可以使用方括号,如下所示:
>>> eng2sp['one'] = 'uno'
>>> eng2sp
{'one': 'uno'}
也可以采用直接给定的“键:值”来创建字典,如下所示:
>>> d = dict(name = 'Dong', age = 37)
>>> print(d)
{'name': 'Dong', 'age': 37}
通过dict转化为字典
如下所示:
>>> keys = ['a','b','c','d']
>>> values = [1,2,3,4]
>>> dictionary = dict(zip(keys,values))
>>> print(dictionary)
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
给定内容为“键”,创建“值”为空的字典:
>>> adict = dict.fromkeys(['name','age','sex'])
>>> print(adict)
{'name': None, 'age': None, 'sex': None}
fromkeys() 方法用于创建一个新的字典,并以可迭代对象中的元素分别作为字典中的键,且所有键对应同一个值,默认为None。
字典的修改
当以指定“键”为下标,并为字典元素赋值时,有两种含义:①若该“键”存在,则表示修改该“键”对应的值;②若该键不存在,则表示添加一个新的“键:值”,也就是添加一个新元素,如下所示:
>>> aDict ={'age':35, 'name':'Dong','sex':'male'}
>>> print(aDict)
{'age': 35, 'name': 'Dong', 'sex': 'male'}
>>> aDict['age'] = 38 #修改元素值
>>> aDict['address'] = 'SDIBT' # 添加新元素
>>> print(aDict)
{'age': 38, 'name': 'Dong', 'sex': 'male', 'address': 'SDIBT'}
添加字典——更新字典
update()方法可以将另一个字典的“键:值”一次性全部添加到当前的字典对象,如果两个字典中存在相同的“键”,则以另外一个字典中的“值”为准对当前字典进行更新,如下所示:
>>> aDict={'age':37, 'score':[98,97],'name':'Dong','sex':'male'}
>>> print(aDict.items())
dict_items([('age', 37), ('score', [98, 97]), ('name', 'Dong'), ('sex', 'male')])
>>> aDict.update({'a':97, 'age':39}) # 修改'age'键的值,同时添加新元素'a':97
>>> print(aDict)
{'age': 39, 'score': [98, 97], 'name': 'Dong', 'sex': 'male', 'a': 97}
删除字典-del函数
del可以删除整个字典,也可以删除字典中指定的元素,如下所示:
>>> aDict={'age':37, 'score':[98,97],'name':'Dong','sex':'male'}
>>> print(aDict)
{'age': 37, 'score': [98, 97], 'name': 'Dong', 'sex': 'male'}
>>> del aDict
>>> print(aDict)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'aDict' is not defined
>>> aDIct
Traceback (most recent call last):
File "", line 1, in
NameError: name 'aDIct' is not defined
删除字典-pop()和popitem()方法
(1)pop() 方法删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
(2)popitem() 方法随机返回并删除字典中的一对键和值(一般删除末尾对)。
如果字典已经为空,却调用了此方法,就报出KeyError异常,如下所示:
>>> aDict={'age':37, 'score':[98,97],'name':'Dong','sex':'male'}
>>> aDict.popitem() # 弹出一个元素,如果是空字典,则会抛出异常
('sex', 'male')
>>> aDict.pop('age')
37
>>> print(aDict) # 弹出指定键对应的元素
{'score': [98, 97], 'name': 'Dong'}
随机删除字典元素
dd.popitem()的功能是随机删除字典中的一个元素,并将所删除的值返回,运行结果如下所示:
>>> dd = {"name":"qiwsir","lang":"python","web":"www.itdiffer.com"}
>>> print(dd.popitem())
('web', 'www.itdiffer.com')
>>> print(dd)
{'name': 'qiwsir', 'lang': 'python'}
字典的清除
字典的清除使用clear()方法,如下所示:
>>> a = {"name":"qiwsir"}
>>> print(a)
{'name': 'qiwsir'}
>>> a.clear()
>>> print(a)
{}
清除与删除是两种不同的操作,如下所示:
>>> a = {"name":"qiwsir"}
>>> print(a)
{'name': 'qiwsir'}
>>> a.clear()
>>> print(a)
{}
>>> del a
>>> print(a)
Traceback (most recent call last):
File "", line 1, in
NameError: name 'a' is not defined
访问项(键:值)
字典中的项没有顺序,因此也没有索引,但可以通过键来直接查找键值,如下所示:
>>> eng2sp = {'one': 'uno', 'three': 'tres', 'two': 'dose'}
>>> eng2sp['three'] = 'tres'
>>> eng2sp['two'] = 'dose'
>>> eng2sp
{'one': 'uno', 'three': 'tres', 'two': 'dose'}
>>> eng2sp
{'one': 'uno', 'three': 'tres', 'two': 'dose}
>>> eng2sp['one']
'uno'
访问项——get()函数
get()函数用法:get() 函数返回指定键的值,如果值不在字典中返回默认值。
>>> aDict={'age':37, 'score':[98,97],'name':'Dong','sex':'male'}
>>> aDict.get('age') # 如果字典中存在该"键",则返回对应的值
37
>>> aDict.get('address','Not Exists') # 指定的"键"不存在,返回指定的默认值
'Not Exists'
访问项——setdefault() 函数
此方法用于返回指定“键”对应的“值”,如果字典中不存在该“键”,就添加一个新元素,并设置该键对应的值,如下所示:
>>> aDict={'age':37, 'score':[98,97],'name':'Dong','sex':'male'}
>>> aDict.setdefault('address','SDIBT') # 添加新元素
'SDIBT'
>>> aDict
{'age': 37, 'score': [98, 97], 'name': 'Dong', 'sex': 'male', 'address': 'SDIBT'}
访问项——遍历字典
对字典对象进行迭代时,默认是遍历字典的键,如果使用items()方法返回字典中的元素,即所有的项(项这里是指“键:值”对)。字典对象的keys()方法返回所有的值,如下所示:
>>> aDict={'age':37, 'score':[98,97],'name':'Dong','sex':'male'}
>>> for item in aDict:
... print(item)
...
age
score
name
sex
>>> for item in aDict.items():
... print(item)
...
('age', 37)
('score', [98, 97])
('name', 'Dong')
('sex', 'male')
>>> aDict.items()
dict_items([('age', 37), ('score', [98, 97]), ('name', 'Dong'), ('sex', 'male')])
>>> aDict.keys()
dict_keys(['age', 'score', 'name', 'sex'])
>>> aDict.values()
dict_values([37, [98, 97], 'Dong', 'male'])
同置函数对字典的处理
内置函数len(),max(),min(),sum(),sorted()以及成员测试运算符in也适用于字典对象,但默认作用于字典的“键”,若想作用于元素,即“键:值”对,则需要使用字典的对象items()方法,若作用于“值”,则需要使用valules()方法。
案例实战:字典应用
案例实战:字典应用
下面的一段代码会生成包括1000个随机字符的字符串,然后统计每具字符的出现次数。
包解释:
-
string:String
模块包含许多有用的常量和类,以及一些不推荐的遗留函数,这些函数也可以作为字符串上的方法使用。此外,Python的内置字符串类支持序列类型(str、Unicode、list、tuple、byteArray、Buffer、xrange)中描述的序列类型方法,以及String方法部分中描述的特定字符串的方法。若要输出格式化字符串,可以使用模板字符串或字符串格式操作部分的%运算符。另外,有关基于正则表达式的字符串函数,请参见re模块。 -
random:
这个模块是用于实现各种分页的伪随机数生成器。对于整数来说,它可以从一个范围内进行均匀选择,对于序列来说,此模块中的有可以均匀选择一个元素的函数,以及生成一个随机排列的列表的耿发,以及用于不放回抽样的函数。
代码解释:
-
ascii_letters
是生成所有字母,从a-z和A-Z -
digits
是生成所有数字0-9. -
punctuation
生成标点符号 -
random.choice
随机选择一个元素
第1种方案:最常规的实现方法
代码如下所示:
import string
import random
x = string.ascii_letters + string.digits + string.punctuation
y = [random.choice(x) for i in range(1000)]
# 生成包含1000个随机字符的列表
z = ''.join(y)
# 把列表中的字符连接成字符串
d = dict()
# 空字典
for ch in z:
d[ch] = d.get(ch,0) + 1
# 修改每个字符的频次
print(d)
运行结果如下所示:
D:\>python test.py
{'}': 11, 'r': 11, 'Z': 15, 'I': 5, 'a': 19, 'T': 13, '#': 15, 'U': 8, '\\': 11, 'g': 15, '-': 10, 'M': 15, '3': 13, 'd': 12, 'K': 14, 'f': 7, 'v': 9, '>': 6, '2': 9, '=': 12, '<': 10, '6': 15, 'm': 16, 'V': 15, '?': 8, 'F': 13, 'c': 15, '5': 17, ')': 11, '!': 5, 'Y': 8, 'l': 15, 'e': 13, 'P': 6, '&': 9, '[': 15, '@': 13, '+': 6, 't': 13, ']': 14, 'O': 12, 'G': 16, 'k': 11, 'R': 16, 'L': 12, '8': 13, '`': 10, 'W': 11, 'S': 15, 'E': 13, 'N': 11, '~': 11, '9': 7, 'i': 9, ',': 12, '_': 10, '|': 9, 'q': 17, 'J': 12, "'": 12, '{': 10, 'u': 6, '1': 9, '0': 8, '$': 11, 'b': 12, 'A': 11, '(': 12, 'z': 5, 'x': 8, '4': 10, '/': 12, '*': 11, 'o': 11, 'p': 11, 'Q': 7, ':': 7, 's': 12, '.': 7, 'D': 4, '^': 6, '%': 8, 'X': 8, '"': 8, 'y': 9, 'w': 9, 'n': 10, 'H': 11, 'B': 9, ';': 10, 'h': 8, 'j': 8, 'C': 3, '7': 3}
第2种方案:上述代码可以更改为:
import string
import random
from collections import defaultdict
x = string.ascii_letters + string.digits + string.punctuation
y = [random.choice(x) for i in range(1000)]
# 生成包含1000个随机字符的列表
z = ''.join(y)
# 把列表中的字符连接成字符串
frequences = defaultdict(int)
print(frequences)
for item in z:
frequences[item] += 1
print(frequences.items())
运行结果如下所示:
D:\>python test.py
defaultdict(, {})
dict_items([('I', 14), ("'", 9), (':', 13), ('|', 9), ('k', 10), ('[', 9), ('E', 13), ('T', 11), ('K', 12), ('n', 18), ('a', 8), ('-', 13), ('Y', 12), ('{', 16), ('2', 11), ('.', 10), ('z', 9), ('?', 15), ('_', 8), ('A', 13), ('U', 11), ('C', 14), ('O', 14), ('1', 11), ('p', 12), ('`', 7), ('6', 11), ('j', 11), ('<', 8), ('$', 16), ('\\', 7), ('Z', 11), ('3', 10), ('W', 14), ('i', 10), ('x', 8), ('q', 9), ('%', 10), ('B', 7), ('M', 12), ('&', 16), ('N', 13), ('9', 14), ('}', 7), ('Q', 8), ('!', 10), ('/', 10), ('J', 13), ('s', 13), ('G', 8), ('5', 11), ('e', 19), ('L', 6), ('u', 9), ('g', 10), ('7', 16), ('f', 8), ('+', 14), ('0', 12), ('"', 10), ('(', 17), ('b', 6), ('>', 9), ('m', 10), ('v', 11), ('h', 12), ('y', 9), ('l', 10), ('r', 16), (']', 13), ('^', 12), ('~', 8), ('4', 14), ('o', 10), ('w', 10), ('@', 11), ('X', 10), ('S', 6), ('#', 10), ('c', 6), ('R', 14), ('H', 15), (',', 8), ('D', 11), ('=', 8), ('8', 5), (')', 11), ('*', 2), ('d', 7), ('V', 11), (';', 5), ('t', 8), ('P', 8), ('F', 4)])
第3种方案:
import string
import random
from collections import Counter
x = string.ascii_letters + string.digits + string.punctuation
y = [random.choice(x) for i in range(1000)]
# 生成包含1000个随机字符的列表
z = ''.join(y)
# 把列表中的字符连接成字符串
frequences = Counter(z)
print(frequences.items())
print(frequences.most_common(1))
print(frequences.most_common(3))
运行结果如下所示:
D:\>python test.py
dict_items([('!', 4), (':', 6), ('A', 9), ('e', 6), ('R', 5), ('*', 16), ('2', 6), ('m', 17), ('"', 6), ('{', 9), ('i', 13), ('\\', 8), ('r', 8), ('/', 10), ('>', 9), ('f', 14), ('#', 18), ('w', 13), (']', 8), ('J', 9), ('V', 12), ('s', 13), ('}', 11), ('Q', 12), ('5', 13), ('k', 9), ('t', 10), ('S', 9), ('=', 7), ('n', 13), ('7', 13), ('p', 7), ('X', 13), ('~', 5), ('.', 15), ('E', 15), ('&', 12), ('B', 9), ('q', 14), ("'", 8), ('U', 13), ('Z', 7), ('F', 9), (',', 13), ('v', 15), ('a', 8), ('P', 12), ('+', 13), ('G', 14), ('@', 21), ('y', 10), ('$', 9), ('j', 16), ('D', 13), ('b', 9), ('z', 12), ('c', 12), ('3', 12), ('0', 11), (')', 11), ('Y', 15), ('d', 11), ('?', 11), ('I', 5), ('L', 13), ('_', 9), ('O', 9), ('(', 7), ('l', 6), ('^', 8), ('%', 9), ('u', 13), ('<', 13), ('`', 10), ('|', 14), ('C', 16), ('1', 11), ('-', 10), ('o', 8), ('x', 8), ('8', 12), ('M', 12), ('g', 13), ('T', 11), (';', 7), ('H', 12), ('6', 10), ('[', 9), ('K', 11), ('9', 10), ('W', 6), ('4', 11), ('h', 12), ('N', 4)])
[('@', 21)]
[('@', 21), ('#', 18), ('m', 17)]
字典排序
内置函数sorted()可以对字典元素进行排序并返回新列表,充分利用key参数可以实现丰富的排序功能,如下所示:
>>> phonebook = {'Linda':'7750','Bob':'9345','Carol':'5834'}
>>> from operator import itemgetter
>>> sorted(phonebook.items(), key=itemgetter(1))
[('Carol', '5834'), ('Linda', '7750'), ('Bob', '9345')]
>>> # 按字典的"值"进行排序
...
>>> sorted(phonebook.items(),key=itemgetter(0))
[('Bob', '9345'), ('Carol', '5834'), ('Linda', '7750')]
>>> #按字典的"键"进行排序
...
>>> sorted(phonebook.items(),key=lambda item:item[0])
[('Bob', '9345'), ('Carol', '5834'), ('Linda', '7750')]
>>> # 按字典的"键"进行排序
提取字典的子集
>>> students_score = {'jack':80,'james':91, 'leo':100, 'sam':60}
>>> # 提取分数超过90分的学生信息,并变成字典
...
>>> print(students_score)
{'jack': 80, 'james': 91, 'leo': 100, 'sam': 60}
>>> good_score = {name:score for name, score in students_score.items() if score > 90}
>>> print(good_score)
{'james': 91, 'leo': 100}
提取字典中的某个键的值
如果此键不在字典中,就会返回none。
>>> d = {'lang':'python'}
>>> print(d)
{'lang': 'python'}
>>> print(d.get("lang"))
python
计算字典的健值
>>> stocks = {'wanke':25.6, 'wulingye':32.4, 'maotai':299.4,'huatai':18.6}
>>> print(stocks)
{'wanke': 25.6, 'wulingye': 32.4, 'maotai': 299.4, 'huatai': 18.6}
>>> print(min(stocks.values()))
18.6
>>> print(max(stocks.values()))
299.4
字典的翻转
>>> stocks = {'wanke':25.6, 'wulingye':32.4, 'maotai':299.4,'huatai':18.6}
>>> print(stocks)
{'wanke': 25.6, 'wulingye': 32.4, 'maotai': 299.4, 'huatai': 18.6}
>>> invert_stocks = dict([(v,k) for k,v in stocks.items()])
>>> print(invert_stocks)
{25.6: 'wanke', 32.4: 'wulingye', 299.4: 'maotai', 18.6: 'huatai'}
字典推导式
字典推导和列表推导的使用方法是类似的,只不中括号该改成大括号。直接举例说明:
案例1:大小写key合并
>>> mcase = {'a': 10, 'b': 34, 'A': 7, 'Z': 3}
>>> mcase_frequency = {
... k.lower(): mcase.get(k.lower(), 0) + mcase.get(k.upper(), 0)
... for k in mcase.keys()
... if k.lower() in ['a','b']
... }
>>> print(mcase_frequency)
{'a': 17, 'b': 34}
案例2:快速更换key和value
>>> mcase = {'a': 10, 'b': 34}
>>> mcase_frequency = {v: k for k, v in mcase.items()}
>>> print(mcase_frequency)
{10: 'a', 34: 'b'}
使用字典推导式生成符合特定条件的字典
>>> {i:str(i) for i in range(1,5)}
{1: '1', 2: '2', 3: '3', 4: '4'}
>>> x = ['A','B','C','D']
>>> y = ['a','b','b','d']
>>> {i:j for i,j in zip(x,y)}
{'A': 'a', 'B': 'b', 'C': 'b', 'D': 'd'}
再看一个案例,在这个案例中,寻找得到分最高的同学:
biotest@biotest-VirtualBox:~/python3/03file$ cat dict1.py
#!/usr/bin/python3
scores = {"Zhang San":45, "Li Si":78, "Wang Wu":40, "Zhou Liu":96, "Zhao Qi":65, "Sun Ba":90, "Zheng Jiu":78, "Wu Shi":99,"Dong Shiyi":60}
print(scores)
higest = max(scores.values())
lowest = min(scores.values())
print(higest)
print(lowest)
average = sum(scores.values())/len(scores)
print(average)
higestPerson = [name for name, score in scores.items() if score == higest]
print(higestPerson)
biotest@biotest-VirtualBox:~/python3/03file$ python3 dict1.py
{'Zhang San': 45, 'Li Si': 78, 'Wang Wu': 40, 'Zhou Liu': 96, 'Zhao Qi': 65, 'Sun Ba': 90, 'Zheng Jiu': 78, 'Wu Shi': 99, 'Dong Shiyi': 60}
99
40
72.33333333333333
['Wu Shi']
使用字典推导式提取字典的键与值
biotest@biotest-VirtualBox:~/python3/03file$ cat test2.py
#!/usr/bin/python3
from random import randint
x = [randint(1,10) for i in range(20)]
# 生成20个范围在1到10之间的随机数
for i in enumerate(x):
print(i)
m = max(x)
print(m)
print([index for index, value in enumerate(x) if value ==m])
print(enumerate(x))
print(x)
biotest@biotest-VirtualBox:~/python3/03file$ python3 test2.py
(0, 10)
(1, 5)
(2, 5)
(3, 2)
(4, 2)
(5, 8)
(6, 4)
(7, 9)
(8, 5)
(9, 2)
(10, 1)
(11, 3)
(12, 9)
(13, 3)
(14, 7)
(15, 6)
(16, 8)
(17, 2)
(18, 10)
(19, 6)
10
[0, 18]
[10, 5, 5, 2, 2, 8, 4, 9, 5, 2, 1, 3, 9, 3, 7, 6, 8, 2, 10, 6]
注1:其中用到了enumerate(),这是python的内置函数、在字典上是枚举、列举的意思,它可以遍历/可迭代的对象(如列表、字符串),enumerate多用于在for循环中得到计数,利用它可以同时获得索引和值,即需要index和value值的时候可以使用enumerate。
注2:如果不用for循环,enumerate()返回的是一个enumerate对象,如下所示:
biotest@biotest-VirtualBox:~/python3/03file$ cat test3.py
#!/usr/bin/python3
from random import randint
x = [randint(1,10) for i in range(20)]
# 生成20个范围在1到10之间的随机数
for i in enumerate(x):
print(i)
print(enumerate(x))
biotest@biotest-VirtualBox:~/python3/03file$ python3 test3.py
(0, 8)
(1, 7)
(2, 2)
(3, 4)
(4, 10)
(5, 4)
(6, 5)
(7, 5)
(8, 6)
(9, 5)
(10, 6)
(11, 3)
(12, 10)
(13, 10)
(14, 7)
(15, 2)
(16, 1)
(17, 7)
(18, 9)
(19, 8)
查看字典元素的多少
使用len()函数,如下所示:
>>> a = {i:str(i) for i in range(1,5)}
>>> a
{1: '1', 2: '2', 3: '3', 4: '4'}
>>> print(len(a))
4
>>>
字典的复制
如果直接用=
复制字典,其实是为同一个对象贴了两个标签,如下所示:
>>> a = 5
>>> print(a)
5
>>> b = a
>>> print(b)
5
>>> print(a,b)
5 5
>>> print(id(a),id(b))
1895588128 1895588128
运行结果如下所示,可以发现,a与d的id是一样的,它们表示的是同一个对象,如果用copy方法来进行复制,如下所示:
>>> ad = {"name":"qiwsir","lang":"python"}
>>> bd = ad
>>> cd = ad.copy()
>>> print(cd)
{'name': 'qiwsir', 'lang': 'python'}
>>> print(id(cd))
2434395979280
>>> print(id(ad))
2434395576072
>>> cd["name"] = "itdiffer.com"
>>> print(cd)
{'name': 'itdiffer.com', 'lang': 'python'}
>>> print(ad)
{'name': 'qiwsir', 'lang': 'python'}
继续修改,如下所示:
>>> bd["name"] = "laoqi"
>>> print(bd)
{'name': 'laoqi', 'lang': 'python'}
>>> print(ad)
{'name': 'laoqi', 'lang': 'python'}
修改了bd所对应的对象后,ad的对象也变了。