书中的这一部分还是感觉写的有点乱。所以我直接合在一起讨论字典,并且补上一点点书上没有的元组的概念。
字典
字典,就你用的英汉字典的感觉,一个词(键)对应一个意思(值),被称为键-值对,键和值之间通过英文冒号配对,键和值的元素的类型也不受限制,也可以套娃(bushi 嵌套。
字典的所有元素都放在一个大括号中 {} 。
访问字典
访问方法与列表几乎相同,前面了解过了列表之后,元组和字典的很多东西都是相通的。
列表访问元素是使用索引,字典的键就相当于索引,所以使用键就可以访问相关的值:
dict_number = {1: 'one', 2: 'two', 3: 'three'}
print(dict_number[2])
结果:
two
修改字典
添加/删除键-值对
前面说过,键类似于列表中的索引,但列表的索引是根据列表中元素的个数及位置来确定的,而键只和值有关,所以我们只需要指定一个新的“索引”并给定其值,那么这一对键值对就被加入字典中了。
dict_666 = {}
dict_666[666] = '666'
print(dict_666)
然后这个键值对就存在字典中了:
{666: '666'}
删除的方法也和列表类似:
dict_666 = {}
dict_666[666] = '666'
dict_666.pop(666)
print(dict_666)
dict_666[666] = '666'
del dict_666[666]
print(dict_666)
打印出来的就是两个空列表了:
{}
{}
若字典中没某个值,则pop()方法需要设置参数“default”,否则则会报错:
对于不存在的索引/键值,则会弹出逗号后面的“备用”值,前面说过被pop方法弹出的值是可以存在变量之中的,所以必须指引一个值使其能被存在变量之中。
字典没有remove()方法。
修改字典中的值
修改的方法和列表也类似,仍然是把列表所使用的索引值改为键值。
dict_666[666] = "777"
print(dict_666)
运行结果:
{666: '777'}
遍历列表
可分为三种情况,字典由键和值组成,可以获取键值对或者分别获取键或值。
获取键值对用items()方法,获取键用keys()方法,获取值用values()方法。
一般字典中的键值对都很多,我们可以采取for循环的方法来获取。
dict_traverse = {1: "好", 2: "家", 3: "伙"}
for key, value in dict_traverse.items():
print(key)
print(value)
for key in dict_traverse.keys():
print(key)
for value in dict_traverse.values():
print(value)
结果不展示了,太长了。。。
多行定义字典
字典的数量可能是庞大的,如果都写在一行上面,未免有些可怕,所以我们可以将字典分成多行来书写:
dict_more_line = {
1: "好",
2: "家",
3: "伙",
}
可以在每一行打完之后都加上英文逗号,哪怕是最后一个,以备不时会创建下一个键值对,最后一个键值对末尾加英文逗号并不违反规则,字典是水平时也可以这样搞。
排序字典
单词sort的意思就是排序,所以在这里sorted()仍然可以排序使用。
1.直接对字典排序,用sorted()函数对字典直接进行排序,生成只包含字典键的列表,默认按升序排列,也可以设置倒序参数reverse为True。
dict_hjh = {1: "好", 2: "家", 3: "伙", }
sort_dict_list = sorted(dict_hjh)
print(sort_dict_list)
结果:
[1, 2, 3]
keys()、values()、items()方法,分别可以把字典中的成分提取出来,再进行后续操作。
dict_empty = {}
dk = dict_empty.keys()
dv = dict_empty.values()
di = dict_empty.items()
print(type(dk))
print(type(dv))
print(type(di))
打印的结果:
<class 'dict_keys'>
<class 'dict_values'>
<class 'dict_items'>
此时对dk、dv、di 使用sorted()函数,可以得到分别按键、值、键值对排列的列表了,对这三个变量使用list()函数,也就相当于提取出来对应的列表,其中键值对会以元组的形式作为列表的元素。(这里的字典是空字典,三个的结果都是空列表,下面用上面的一个字典为示例)
[(1, '好'), (2, '家'), (3, '伙')]
上面的结果,是一个以元组为元素的列表,书中说到的可以通过匿名函数lambda(读λ)设置排序字段为值,就是按值排序,其实这个说法不太准确,因为它排序完也不是字典了,而是一个以元组为元素的列表,,,以元组为元素的列表?,刚刚那个不就是?你再看书上写的表达式,括号里面不就是一个items()方法,导致生成了一个以元组为元素的列表嘛。emmm...我们接下来好好捋一捋这个什么玩意lambda函数。(这个函数算是进阶语法,个人感觉不会也罢)
lambda [arg1 [,arg2,.....argn]]:expression
这个函数叫匿名函数,为啥叫匿名函数呢?因为他可以不定义函数名就定义函数,后面会学到一个def 用来定义函数,为了定义一个函数会写一大堆好几串,但是可能有时候你就是为了临时某一行代码需要用一个函数,那么再去想个名字好像太麻烦。。
所以这个东西可以看做是一个简单的小函数生成器,可以生成一个有名函数,也可以生成一个无名的,更重要的是简洁:
xyz = lambda x, y, z: x*y*z
print(xyz(5, 6, 9))
print(xyz(59, 64, 97))
print(xyz(544, 658, 459))
例如这样,你就生成了一个可以输入三个数据(元组)的小函数。这个函数的作用是让输入的三个数相乘。运行结果如下:
270
366272
164299968
还可以不定义函数名,直接把数据放在后面,就可以使用。
print((lambda x, y, z: x ** y ** z)(6, 6, 3))
输出:......
1204120867648235108202090056857283403336732693457453224358121221145020555710636789704085475234591191603986789604949502079328192358826561895781636115334656050057189523456
别问我为什么不用三个6:
那么,既然可以不命名函数,可以写到一行里面,就是说可以嵌套到其他函数里面
所以我们的主角,sorted函数就该出场了,这个函数还是比较牛的,具体的用法引用别的地方一下:
- key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。
我们主要看一下这个key,以上这个解释好多地方都能找到。
那么什么情况会遇见要指定可迭代对象中的元素,以及怎么指定,其实就是刚刚所说的:由元组为元素组成的列表,元组是不可变的,列表是可变的,元组和列表一样都有索引,且也是从0开始。
所以,我们可以用lambda函数对上面的列表进行排序。
比如说,我们需要告诉key需要按第三个排序,但是每个元组的第三个元素都不一样,,,
所以我们需要分别访问元组的第三个元素,欸,这是不是可以写一个函数来分别访问,还需要让这个函数能放在key后面,这不就是lambda函数干的事情吗?
所以:
list_tuple = [(1, 2, 3), (3, 1, 2), (3, 2, 1)]
sort_list = sorted(list_tuple, key=lambda x: x[2])
print(sort_list)
结果:
[(3, 2, 1), (3, 1, 2), (1, 2, 3)]
而书上使用了items函数之后,字典phone其实就已经不是字典了,整个排序过程就是一个类似上面的排序。
书照片
那么怎么按值排序字典呢?
a = {'b': 3, 'a': 2, 'd': 4, 'c': 1}
b = a.items()
c = list(b)
d = sorted(c, key=lambda x: x[1])
e = dict((x, y) for x, y in d)
print(e)
只需要在按元组的第二项排序完之后再转换为字典就好了,结果如下:
{'c': 1, 'a': 2, 'b': 3, 'd': 4}
# 累了不想写了,感觉这个书真的不是很好,写下去没啥必要,建议大家去看:
这个书还是写的很不错的,逻辑也比较清晰,我原本是打算写完这本书的笔记的,但是自从看见了那个lambda函数,,,就感觉 ,,这书怎么这么早就讲这种函数,感觉不太妥,最终放弃了这本书。。
如果你看完上面那个书,可以去看Python的黑书,就是机械工业出版社引进的那本。