目录
概述
使用键-值(key-value)存储,具有极快的查找速度
注意:字典是无序的
key的特性:
1.key必须是不可变对象
2.字符串、整数等都是不可变的,可以作为key
3.list是可变的,不能作为key
value:可以为任何数据类型:元组、字符串…
思考:如何保存多位学生的姓名与成绩 。
使用字典,学生姓名为key,学生成绩作为值
一、元素的访问
获取:字典名[key]
dict1 = {"tom":60, "lilei":70}
print(dict1["lilei"]) #输出:70
#print(dict1["luck"]) 报错因为字典里没有luck
ret = print(dict1.get("luck")) #None
if ret == None:
print("没有")
else:
print("有")
二、字典的添加
dict1 = {"tom":60, "lilei":70}
dict1["hanmeimei"] = 99 #添加了"hanmeimei":99
print(dict1) #{'tom': 60, 'lilei': 70, 'hanmeimei': 99}
#因为一个key对应一个value,所以,多次对一个key的value赋值其实就是修改值
dict1["lilei"] = 80 #将字典里原有的覆盖了
#得到{'tom': 60, 'lilei': 80, 'hanmeimei': 99}
三、字典的删除
dict1 = {"tom":60, "lilei":70}
dict1.pop("tom")
print(dict1)
#输出:{'lilei': 70}
四、遍历
dict1 = {"tom":60, "lilei":70}
for key in dict1:
print(key, dict1[key])
'''
输出:
tom 60
lilei 70
'''
五、字典方法
(一)Dictionary.values( )
字典values() 函数以列表返回字典中的所有值。
dict1 = {"tom":60, "lilei":70, "hanmeimei":99}
print(dict1.values()) #dict_values([60, 70, 99])
#打印出来是一个列表
for value in dict1.values():
print(value) #[60,70,90]
(二)Dictionary.items( )
字典items() 函数以列表返回可遍历的(键, 值) 元组数组。
dict1 = {"tom":60, "lilei":70, "hanmeimei":99}
print(dict1.items())
#是一个列表,列表下有很多元组 dict_items([('tom', 60), ('lilei', 70), ('hanmeimei', 99)])
for k, v in dict1.items():
print(k, v)
'''
tom 60
lilei 70
hanmeimei 99
'''
(三)enumerate
for i, v2 in enumerate(dict1):
print(i, v2)
'''
0 tom
1 lilei
2 hanmeimei
'''
六、字典和列表的比较
字典:1、字典查找和插入的速度极快,不会随着key-value的增加而变慢。
2、字典需要占用大量的内存,内存浪费多。
列表:1、查找和插入的速度随着数据量的增多而减慢
2、占用空间小,浪费内存少
七、练习
(一)单词在句子中出现的次数
任意输入一个单词,输出该单词在特定的句子中出现的次数。(不使用count)
思考实现该功能要怎么做?
1、以空格切割字符串
2、循环处理列表中的每个元素
3、以元素当做key去一个字典中提取数据
4、如果没有提取到,就以该元素作为key,1作为value存进字典
5、如果提取到,将对应的key的value修改,值加1
6、根据输入的字符串当做key再去字典取值
w = input()
d = {} #创建了一个空字典
str = "You never know your luck! You will know your luck! " \
"I never know your luck! I will know luck! You never " \
"never never know your luck!"
l = str.split(" ")#返回分割后的字符串列表
print(l)
#['You', 'never', 'know', 'your', 'luck!', 'You', 'will', 'know', 'your', 'luck!', 'I', 'never', 'know', 'your', 'luck!', 'I', 'will', 'know', 'luck!', 'You', 'never', 'never', 'never', 'know', 'your', 'luck!']
for v in l:
c = d.get(v) #返回指定键的值,如果值不在字典中返回默认值None
if c == None:
d[v] = 1
else:
d[v] += 1
print(d[w])
#dict.get(key, default=None)
#key -- 字典中要查找的键。
#default -- 如果指定键的值不存在时,返回该默认值。
(二)歌词解析
输入一个时间,得到该时间对应的歌词。
lrcDict = {}
musicLrc = """[00:03.50]传奇
[00:19.10]作词:刘兵 作曲:李健
[00:20.60]演唱:王菲
[00:20.60]
[04:40.75][02:39.90][00:36.25]只是因为在人群中多看了你一眼
[04:49.00]
[02:47.44][00:43.69]再也没能忘掉你容颜
[02:54.83][00:51.24]梦想着偶然能有一天再相见
[03:02.32][00:58.75]从此我开始孤单思念
[03:08.15][01:04.30]
[03:09.35][01:05.30]想你时你在天边
[03:16.90][01:13.13]想你时你在眼前
[03:24.42][01:20.92]想你时你在脑海
[03:31.85][01:28.44]想你时你在心田
[03:38.67][01:35.05]
[04:09.96][03:39.87][01:36.25]宁愿相信我们前世有约
[04:16.37][03:46.38][01:42.47]今生的爱情故事 不会再改变
[04:24.82][03:53.83][01:51.18]宁愿用这一生等你发现
[04:31.38][04:01.40][01:57.43]我一直在你身旁 从未走远
[04:39.55][04:09.00][02:07.85]
"""
musicLrcList = musicLrc.splitlines()#按照行('\r', '\r\n', \n')分隔,返回一个包含各行作为元素的列表
#print(musicLrcList)
'''
['[00:03.50]传奇', '[00:19.10]作词:刘兵 作曲:李健', '[00:20.60]演唱:王菲',
'[00:20.60]', '[04:40.75][02:39.90][00:36.25]只是因为在人群中多看了你一眼', '[04:49.00]',
'[02:47.44][00:43.69]再也没能忘掉你容颜', '[02:54.83][00:51.24]梦想着偶然能有一天再相见',
'[03:02.32][00:58.75]从此我开始孤单思念', '[03:08.15][01:04.30]', '[03:09.35][01:05.30]想你时你在天边',
'[03:16.90][01:13.13]想你时你在眼前', '[03:24.42][01:20.92]想你时你在脑海', '[03:31.85][01:28.44]想你时你在心田',
'[03:38.67][01:35.05]', '[04:09.96][03:39.87][01:36.25]宁愿相信我们前世有约',
'[04:16.37][03:46.38][01:42.47]今生的爱情故事 不会再改变', '[04:24.82][03:53.83][01:51.18]宁愿用这一生等你发现',
'[04:31.38][04:01.40][01:57.43]我一直在你身旁 从未走远', '[04:39.55][04:09.00][02:07.85]']
'''
for lrcLine in musicLrcList:
lrcLineList = lrcLine.split("]")
#print(lrcLineList)
#我们将每个元素以“]”分隔开来。
#例:[04:40.75][02:39.90][00:36.25]只是因为在人群中多看了你一眼 变成了
#['[04:40.75', '[02:39.90', '[00:36.25', '只是因为在人群中多看了你一眼']
for index in range(len(lrcLineList) - 1): #range(列表中元素个数 - 1) 将歌词剔除循环的范围,只剩下了时间 即:['[04:40.75', '[02:39.90', '[00:36.25','只是因为在人群中多看了你一眼'不参与循环]
timeStr = lrcLineList[index][1:] #取出第index个列表里除了第一个元素的所有元素(第一个是“[”),这样就只剩下了时间。
#print(timeStr)
#04:40.75 02:39.90 00:36.25
timeList = timeStr.split(":") #将时间以冒号分隔开
#print(timeList) #['04', '40.75'] ['02', '39.90'] ['00', '36.25']
time1 = float(timeList[0]) * 60 + float(timeList[1]) #将时间都转为秒 280.75 159.9 36.25
#print(time)
# 00:03.50 → 3.5
lrcDict[time1] = lrcLineList[-1] #将时间,以及每个时间对应的歌词存放到一个字典里
#print(lrcDict)
#{3.5: '传奇', 19.1: '作词:刘兵 作曲:李健', .........
allTimeList = []
for t in lrcDict:
allTimeList.append(t)#将t添加到列表末尾,列表里存放所有时间
#print(t, lrcDict[t])
#print(allTimeList)
allTimeList.sort()#对原列表进行排序 默认升序
print(allTimeList)
while 1:
getTime = float(input("请输入一个时间"))
for n in range(len(allTimeList)):
tempTime = allTimeList[n] #将输入的时间与列表里所有的时间比较,直到找到大于输入的时间那个值时,该循环结束。
if getTime < tempTime:
break
if n == 0:
print("时间太小")
else:
print(lrcDict[allTimeList[n - 1]]) #该时间输出对应的歌词
#-----------------------------------------------------
#3.5 1111 如果输入的时间为20,则输出2222
#19.1 2222
#20.6 3333
#36.25 4444
#-----------------------------------------------------
#这样我们输入一个时间,会得到该时间对应的歌词
如果我们想要做一个自动提词器,歌词可以自动滚动,要在以上程序的基础上导入time(import time),并且将程序末尾的while语句修改成下面的样子,我们就可以看到歌词自动滚动了,不过这样仍然有很多缺陷需要改进,大家有兴趣可以自己研究。
getTime = 0
while 1:
for n in range(len(allTimeList)):
tempTime = allTimeList[n]
if getTime < tempTime:
break
lrc = lrcDict.get(allTimeList[n - 1])
if lrc == None:
pass
else:
print(lrc)
time.sleep(1.0)
getTime += 1