字典
示例:利用列表实现摩斯密码
c_table = [".-", "-...", "-.-.", "-..", ".", "..-.",
"--.", "....", "..", ".---", "-.-", ".-..",
"--", "-.", "---", ".--.", "--.-", ".-.",
"...", "-", "..-", "...-", ".--", "-..-",
"-.--", "--..", ".----", "..---", "...--", "....-",
".....", "-....", "--...", "---..", "----.", "-----"]
d_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"]
#设密
[c_table[d_table.index(i)] for i in 'ASDFGH']
['.-', '...', '-..', '..-.', '--.', '....'] #输出结果
#解密
code = ".- ... -.. ..-. --. ...."
new = code.split(" ")
# new = ['.-', '...', '-..', '..-.', '--.', '....']
[d_table[c_table.index(i)] for i in new] #输出结果
['A', 'S', 'D', 'F', 'G', 'H']
(或使用一个列表表示映射)
# 摩斯密码对比表
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[c_table.index(each) + 1] for each in split_code]
print(result)
利用字典实现摩斯密码
# 摩斯密码对比表
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 = ".- ... -.. ..-. --. ...."
new = code.split(" ")
[c_table[i] for i in new]
['A', 'S', 'D', 'F', 'G', 'H'] #输出结果
其他:
>>> type(c_table)
<class 'dict'>
>>> c_table['.-']
'A'
创建字典
①其中冒号左侧为“键”,右侧为“值”
a = {"A":"AA","B":"BB","C":"CC"}
②与 list()、tuple()、str() 同理,每个参数是一个键值对
b = dict(A="AA",B="BB",C="CC")
③用列表作参数,列表中每个元素是用元组包裹的键值对
c = dict([("A","AA"),("B","BB"),("C","CC")])
增添 & 修改
fromkeys(iterable, [value]):
使用 iterable 参数指定的可迭代对象来创建一个新字典,并将所有的值初始化为 value 参数指定的值。
>>> d = dict.fromkeys("Fish", 250)
>>> d
{'F': 250, 'i': 250, 's': 250, 'h': 250}
>>> d = dict.fromkeys("Fish") #不指定value参数则采用默认值 None
>>> d
{'F': None, 'i': None, 's': None, 'h': None}
该方法可以快速初始化一个字典。
注:键必须不可变,所以可以用数字,字符串或元组充当,用列表不行。错误示例:
>>> tinydict = {['Name']: 'Zara', 'Age': 7}
删除
pop() 删除指定元素:
>>> d
{'F': None, 'i': None, 's': None, 'h': None, 'C': 67}
>>> d.pop('s')
>>> d
{'F': None, 'i': None, 'h': None, 'C': 67}
>>> d.pop("狗", "没有~")
'没有~'
pop(key[,default]) 删除字典给定键 key 所对应的值,返回值为被删除的值。key值必须给出。 否则,返回default值。
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 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
{}
修改
若要修改某个键的值:
>>> 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}
如果在字典中找不到对应键,则变成新加一个键值对:
>>> d['A'] = 67
>>> d
{'F': None, 'i': None, 's': 115, 'h': None, 'C': None, 'A': 67}
同时修改多个键值对:
可使用字典的 update() 方法,同时传入多个键值对;
也可传入另一个字典,或一个包含键值对的可迭代对象。
>>> d
{'F': None, 'i': None, 's': 115, 'h': None, 'C': None}
>>> 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'}
查找
最简单:
>>> d['C']
67
有反应:
>>> 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'}
视图对象
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])
浅拷贝(拷贝后,原字典改变不影响拷贝结果):
>>> e = d.copy()
>>> e
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
操作
len() 求键值对数量
in 和 not in 判断是否在字典中
list(x) 将字典x转化为列表:得到所有“键”构成的列表
>>> list(d)
['F', 'i', 's', 'h', 'C']
list(x.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
reversed() 对字典内部的键值对进行逆向操作
>>> list(reversed(d))
['C', 'h', 's', 'i', 'F']
同理:
>>> list(reversed(d.values()))
[67, 104, 115, 105, 70]
dict.get(key, default=None) 返回指定键的值,如果值不在字典中返回default值
dict.has_key(key) 如果键在字典dict里返回true,否则返回false
dict.keys() 以列表返回一个字典所有的键
dict.values() 以列表返回字典中的所有值
dict.setdefault(key, default=None) 和get()类似, 但如果键不存在于字典中,将会添加键并将值设为default
嵌套
字典嵌套字典:
>>> d = {"吕布": {"语文":60, "数学":70, "英语":80}, "关羽": {"语文":80, "数学":90, "英语":70}}
>>> d["吕布"]["数学"]
70
字典嵌套列表:
>>> d = {"吕布": [60, 70, 80], "关羽": [80, 90, 70]}
>>> d["吕布"][1]
70
字典推导式
键值调换位置:
>>> d = {'F':70, 'i':105, 's':115, 'h':104, 'C':67}
>>> c = {a:b for b,a in d.items()}
>>> c
{70: 'F', 105: 'i', 115: 's', 104: 'h', 67: 'C'}
>>> e = {a:b for b,a in d.items() if a > 100}
>>> e
{105: 'i', 115: 's', 104: 'h'}
>>> d.items() #补充
dict_items([('F', 70), ('i', 105), ('s', 115), ('h', 104), ('C', 67)])
利用字典推导式轻松求出字符串的编码值:
>>> d = {x:ord(x) for x in "FishC"}
>>> d
{'F': 70, 'i': 105, 's': 115, 'h': 104, 'C': 67}
集合
创建一个集合通常有三种方法:
- 使用花括号,元素间以逗号分隔:{“FishC”, “Python”}
- 使用集合推导式:{s for s in “FishC”}
- 使用类型构造器,也就是 set():set(“FishC”)
集合随机性
集合具有随机性/无序性,不可使用下标索引访问,可使用 in 和 not in 判断:
>>> set("FishC")
{'i', 'C', 's', 'F', 'h'}
>>> 'C' in s
True
>>> 'c' not in s
True
访问集合
迭代方式:
>>> for each in s:
... print(each)
...
F
h
i
s
C
集合唯一性
可利用该特性去重/检验列表中是否存在重复元素:
>>> s = [1, 2, 3, 4, 4]
>>> set(s)
{1, 2, 3, 4}
>>> len(s) == len(set(s))
False
集合的方法
集合分为可变 set() 和不可变 frozenset() 。
也可使用运算符:
子集(<=),真子集(<),超集,真超集
并集:
>>> s | {1, 2, 3} | set("Python")
{1, 2, 3, 'y', 'h', 'n', 'i', 'P', 's', 'o', 't', 'C', 'F'}
交集:
>>> s & set("Php") & set("Python")
{'h'}
差集:
>>> s - set("Php") - set("Python")
{'s', 'C', 'F', 'i'}
对称差集:
>>> s ^ set("Python")
{'t', 'y', 'F', 's', 'P', 'C', 'n', 'o', 'i'}
添加一个:add
添加多个:update
删除一个:remove或discard
删除一个/多个:difference_update
可哈希
可哈希:数据结构不可变,即哈希值在其整个程序的生命周期中都保持不变。
获取哈希值:
>>> hash(1)
1
>>> hash(1.0)
1
>>> hash(1.001)
2305843009213441
Python 中大多数不可变对象是可哈希的,而那些可变的容器则不哈希:
>>> hash("FishC")
2090433017907150752
>>> hash([1, 2, 3])
Traceback (most recent call last):
File "<pyshell#36>", line 1, in <module>
hash([1, 2, 3])
TypeError: unhashable type: 'list'
将列表替换为元组则不可变(可哈希):
>>> hash((1, 2, 3))
529344067295497451
只有可哈希的对象才可作为字典的键以及集合的元素。
集合的嵌套
集合是一个可变的容器(不可哈希),需使用frozenset()
>>> x = frozenset(x)
>>> y = {x, 4, 5}
>>> y
{frozenset({1, 2, 3}), 4, 5}