1. 前言
字典,是Python中唯一实现了映射关系的内置类型。
2.映射关系
摩斯密码就是通过映射关系来实现的。
这里的字母 A 和 .- 就是其中的一对映射关系,字母 U 和 …- 又是另一对映射关系,那么有了这张表,破解莫斯密码就不再是什么难题了。
3.字典实现摩斯密码的破解
# 摩斯密码对比表
c_table = {".-":"A", "-...":"B", "-.-.":"C", "-..":"D",
".":"E", "..-.":"F", "--.":"G", "....":"H",
"..":"I", ".---":"J", "-.-":"K", ".-..":"L",
"--":"M", "-.":"N", "---":"O", ".--.":"P",
"--.-":"Q", ".-.":"R", "...":"S", "-":"T",
"..-":"U", "...-":"V", ".--":"W", "-..-":"X",
"-.--":"Y", "--..":"Z", ".----":"1", "..---":"2",
"...--":"3", "....-":"4", ".....":"5", "-....":"6",
"--...":"7", "---..":"8", "----.":"9", "-----":"0"}
code = input("请输入摩斯密码:")
split_code = code.split(" ")
result = [c_table[each] for each in split_code]
print(result)
列表也可实现,但和字典相比较下,字典的效率更快。
4.字典的关键特征
字典是 Python 中唯一实现映射关系的内置类型。
字典的关键符号是大括号({})和冒号(:):
>>> d = {"吕布":"口口布", "关羽":"关习习"}
>>> type(d)
<class 'dict'>
这里就是两对映射关系,我们将冒号的左边称为字典的 “键”,右边称为字典的 “值”。
在字典中,只要我们提供键,就可以获取其对应的值。方法跟序列类似,只不过这次在方括号中,咱们使用的是键,而非索引值:
>>> d["吕布"]
'口口布'
5.创建字典
一共有六种官方创建字典的方法
(1)第一种就是刚刚给大家演示过的,直接使用大括号和冒号的组合,将映射关系给“套牢”:
>>> a = {"吕布":"口口布", "关羽":"关习习", "刘备":"刘baby"}
(2)第二种,使用 dict() 函数,跟 list()、tuple()、str() 类似,dict() 函数用来生成字典,它的每个参数就是一个键值对,键与值直接使用等号挂钩:
>>> b = dict(吕布="口口布", 关羽="关习习", 刘备="刘baby")
注意:这种写法要求你不能往键上面加引号,尽管它是一个字符串,但是你加引号就会出错,至于为什么嘛……等大家学到函数那一个章节,自然就会无师自通了。
(3)第三种,使用列表作为参数,列表中的每个元素是使用元组包裹起来的键值对:
>>> c = dict([("吕布","口口布"), ("关羽","关习习"), ("刘备","刘baby")])
(4)第四种,属于“无病呻吟”版本,就是将第一种方法作为参数给到 dict() 函数:
>>> d = dict({"刘备": "刘baby", "关羽": "关习习", "吕布": "口口布"})
(5)第五种,混合拳法:
>>> e = dict({"吕布":"口口布", "刘备":"刘baby"}, 关羽="关习习")
(6)第六种,zip() 函数大家应该还有印象吧?它的作用是创建一个聚合多个可迭代对象的迭代器,对吧?那么,它也是可以作为参数传给 dict() 函数的:
>>> f = dict(zip(["吕布","关羽","刘备"], ["口口布","关习习","刘baby"]))
6.字典的增
首先是 fromkeys(iterable[, value]) 方法,这个可以算是字典中最特殊的方法,它可以使用 iterable 参数指定的可迭代对象来创建一个新字典,并将所有的值初始化为 value 参数指定的值:
>>> d = dict.fromkeys("Fish", 250)
>>> d
{'F': 250, 'i': 250, 's': 250, 'h': 250}
如果不指定 value 参数,则采用默认值 None:
>>> d = dict.fromkeys("Fish")
>>> d
{'F': None, 'i': None, 's': None, 'h': None}
这种方法适用于从无到有,创建一个所有键的值都相同的字典。
这招对于快速初始化一个字典非常有用,如果需要修改某个键的值,这么做:
>>> d['F'] = 70
>>> d
{'F': 70, 'i': None, 's': None, 'h': None}
如果在字典中找不到对应的键,那么同样的操作就会变成增加一个新的键值对:
>>> d['C'] = 67
>>> d
{'F': 70, 'i': None, 's': None, 'h': None, 'C': 67}
7.字典的删
删除字典中的指定元素我们可以使用 pop() 方法:
>>> d.pop('s')
>>> d
{'F': None, 'i': None, 'h': None, 'C': 67}
那么你会发现,如果 pop() 一个不存在的键,那么会抛出异常:
>>> d.pop("狗")
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
d.pop("狗")
KeyError: '狗'
如果你想让 Python 别这么激动,可以指定一个 default 参数:
>>> d.pop("狗", "没有~")
'没有~'
跟 pop() 方法类似的还有一个 popitem(),在 Python3.7 之前,它是随机删除一个键值对,在 Python3.7 之后,它删除的是最后一个加入字典的键值对:
>>> d.popitem()
('C', 67)
>>> d
{'F': None, 'i': None, 'h': None}
然后 del 关键字也可以删除一个指定的字典元素
>>> del d['i']
>>> d
{'F': None, 'h': None}
当然,如果 del 直接加上字典的变量名就是将整个字典给干掉:
>>> del d
>>> d
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
d
NameError: name 'd' is not defined
如果我们只希望清空字典中的内容,可以使用 clear() 方法:
>>> d = dict.fromkeys("FishC", 250)
>>> d
{'F': 250, 'i': 250, 's': 250, 'h': 250, 'C': 250}
>>> d.clear()
>>> d
{}
8.字典的改
类似于序列的操作,只需要指定一个存在于字典中的键,就可以修改其对应的值:
>>> d = dict.fromkeys("FishC")
>>> d
{'F': None, 'i': None, 's': None, 'h': None, 'C': None}
>>> d['s'] = 115
>>> d
{'F': None, 'i': None, 's': 115, 'h': None, 'C': None}
如果我们想要同时修改多个键值对,那么说实话,逐个操作就有点太麻烦了。
这时候,我们可以使用字典的 update() 方法,可以同时给它传入多个键值对,也可以直接给它传入另外一个字典,或者一个包含键值对的可迭代对象:
>>> d.update({'i':105, 'h':104})
>>> d
{'F': None, 'i': 105, 's': 115, 'h': 104, 'C': None}
>>> d.update(F='70', C='67')
>>> d
{'F': '70', 'i': 105, 's': 115, 'h': 104, 'C': '67'}
9.字典的查
最简单的查方法就是你给它一个键,它返回你对应的值:
>>> d['C']
67
如果指定的键不存在于字典中,那么会报错:
>>> d['c']
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
d['c']
KeyError: 'c'
这在有些时候会被认为是用户体验不佳的表现,所以更好的方法是使用 get() 方法,它可以传入一个 default 参数,指定找不到键时返回的值:
>>> d.get('c', "这里没有c")
'这里没有c'
还有一种情况是我们需要查找一个键是否存在于字典中,如果在,返回它对应的值;如果不在,给它指定一个新的值:
>>> d.setdefault('C', "code")
67
>>> d
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
>>> d.setdefault('c', "code")
'code'
>>> d
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67, 'c': 'code'}
10.视图对象
items()、keys() 和 values() 三个方法分别用于获取字典的键值对、键和值三者的视图对象。
什么是视图对象呢?
这个名字听着挺新鲜,字面上的解释是:视图对象就是字典的一个动态视图,这意味着当字典内容改变时,视图对象的内容也会相应地跟着改变。
举个例子:
>>> d
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67, 'c': 'code'}
>>> items = d.items()
>>> keys = d.keys()
>>> values = d.values()
>>> items
dict_items([('F', 70), ('i', 105), ('s', 115), ('h', 104), ('C', 67), ('c', 'code')])
>>> keys
dict_keys(['F', 'i', 's', 'h', 'C', 'c'])
>>> values
dict_values([70, 105, 115, 104, 67, 'code'])
>>> d.pop('c')
'code'
>>> items
dict_items([('F', 70), ('i', 105), ('s', 115), ('h', 104), ('C', 67)])
>>> keys
dict_keys(['F', 'i', 's', 'h', 'C'])
>>> values
dict_values([70, 105, 115, 104, 67])
最后,为了方便地实现浅拷贝,字典也提供了一个 copy() 方法:
>>> e = d.copy()
>>> e
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
11.我们可以对字典做什么?
比如,使用 len() 函数来获取字典的键值对数量:
>>> len(d)
5
使用 in 和 not in 来判断某个键是否存在于字典中:
>>> 'C' in d
True
>>> 'c' not in d
True
字典也可以转化为列表,使用 list() 函数就可以了:
>>> list(d)
['F', 'i', 's', 'h', 'C']
list(d) 得到的是字典中所有的 “键” 构成的列表,要得到所有的 “值”,应该使用 list(d.values()):
>>> list(d.values())
[70, 105, 115, 104, 67]
那么 iter() 函数也可以作用于字典,它会将字典的键构成一个迭代器:
>>> e = iter(d)
>>> next(e)
'F'
>>> next(e)
'i'
>>> next(e)
's'
>>> next(e)
'h'
>>> next(e)
'C'
>>> next(e)
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
next(e)
StopIteration
在 Python3.8 之后的版本中,咱们可以使用 reversed() 函数对字典内部的键值对进行逆向操作:
>>> list(reversed(d))
['C', 'h', 's', 'i', 'F']
可以看出,reversed(d) 其实相当于 reversed(d.keys()) 的缩写,那么如果我们想要获得值的逆向序列,可以这么做:
>>> list(reversed(d.values()))
[67, 104, 115, 105, 70]
12.字典的嵌套
字典也是可以嵌套的,某个键的值是另外一个字典,并不是什么稀奇的事儿,举个例子,假如三国也有语数英:
>>> d = {"吕布": {"语文":60, "数学":70, "英语":80}, "关羽": {"语文":80, "数学":90, "英语":70}}
如果想要获取吕布的数学成绩,那么就需要进行两次索引:
>>> d["吕布"]["数学"]
70
那嵌套的也可以是一个列表:
>>> d = {"吕布": [60, 70, 80], "关羽": [80, 90, 70]}
第二次索引,我们当然也得换成下标索引:
>>> d["吕布"][1]
70
13.字典的推导式
好了,最后来个高阶的 —— 字典推导式:
>>> d = {'F':70, 'i':105, 's':115, 'h':104, 'C':67}
>>> b = {v:k for k,v in d.items()}
>>> b
{70: 'F', 105: 'i', 115: 's', 104: 'h', 67: 'C'}
>>> d
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
看,这样我们轻而易举地将键和值给掉了个位置。
当然,我们也可以加上筛选的条件:
>>> c = {v:k for k,v in d.items() if v > 100}
>>> c
{105: 'i', 115: 's', 104: 'h'}
利用字典推导式,我们就可以轻易地让 Python 帮你求出字符串的编码值:
>>> d = {x:ord(x) for x in "FishC"}
>>> d
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}