【引言】如果保持数据有序并不重要而结构很重要,那么可以考虑python中的另外两种内置的无序数据结构——字典和集合。
1.字典的概念
1.python字典允许存储一个键/值对集合。在字典中每个唯一键有一个与之关联的值,字典可以包含多个键/值对。与键关联的value值可以是任意数据类型:int float long list tuple set dict。
2.字典是无序而且可变的。可以把python字典想成一个两列多行的数据结构。与列表类似,字典可以根据需要扩展和收缩。
【注意】
1).键(key)一般是唯一的,如果重复最后的一个键值对会替换前面的,值(value)不需要唯一。
2 ) .字典是不支持索引和切片的
2.字典的创建
字典的创建一共有四种方法:
1).key-value键值对创建
2).内建方法fromkeys
3).zip间接创建
4).dict工厂函数创建
1.key-value键值对创建
与键关联的value值是int类型:
与键关联的value值是set类型:
与键关联的value值是list类型:
与键关联的value值是dict类型(字典的嵌套):
2.内建方法:fromkeys
根据序列依次创建多个key-value对, key值是序列的每个元素, value相同(如果没有指定, 全为None; 如果指定了, 为指定的内容)
应用场景: 批量生成银行卡号;批量生成value值相同的信息;
3.zip间接创建
4.dict工厂函数创建
小栗子:
需求: 创建100个银行卡号, 6103452xxx: 6103452001, 6103452002,…6103452100, 这些银行卡号的初始密码为666666.
#1). 生成100个卡号, 存储在列表中
cards = []
for count in range(100):
num = "%.3d" %(count+1) ##%.3d表示占三位,左边要对齐;%3.d表示占三位右对齐
card = '6103452' + str(num)
cards.append(card)
# 2). 快速生成卡号和密码的对应关系, 存储在字典中;
cards_info = {}.fromkeys(cards, 'westos')
print(cards_info)
结果展示在了一行,这样不友好,因此导入一个pprint模块。
# pprint==pretty print,更加美观/友好的打印模块
import pprint
cards = []
for count in range(100):
num = "%.3d" %(count+1)
card = '6103452' + str(num)
cards.append(card)
cards_info = {}.fromkeys(cards, 'westos')
pprint.pprint(cards_info)
结果展示比较友好
3.字典的特性
字典不支持索引
字典不支持切片
字典的重复和连接是无意义的,字典的key值是唯一的
成员操作符:判断的是 某个值是否为字典的key
for循环:
1)遍历字典的key值
2)遍历字典
4.字典的键值对增加
一共有三种方式:
1).根据key值增加;services[key]
2).update添加多个键值对
3).setdefault
1. 增加一个元素
a.如果key值存在,则更新对应的value值
b.如果key值不存在,则添加对应的key-value值
2. 添加多个key-value值(update方法)
a.如果key值存在,则更新对应的value值
b.如果key值不存在,则添加对应的key-value值
3. setdefault添加key值
a.如果key值存在,则不做修改
b.如果key值不存在,则添加对应的key-value值
【补充】
if key in dic:
语句A
else:
语句B
可以用not in替换。
if key not in dic:
语句B
更进一步可以使用setdefault方法替换那两行if not in。
dic.setdefault( key , value)
利用这个方法可以保证使用一个键之前总会将它初始化位一个初始值,同时如果这个键已经存在,调用setdefault没有任何影响.
5.字典的键值对删除
一共有四种方式:
1)del关键字
2 ) pop函数
3 ) popitem函数
4 ) clear函数
1.del关键字,删除对应的键值对
2.pop删除指定的key的key-value值
a.如果key存在,删除,并且返回删除key对应的value值
b.如果key不存在,如果没有提供默认值, 则抛出异常KeyError
students = {
'user1': [100, 100, 100],
'user2': [98, 100, 100],
'user3': [100, 89, 100],
}
delete_item = students.pop('user6', 'no user') #设置了默认值为‘no user’
print("删除的元素是: ", delete_item)
print(students)
3.popitem随机删除key-value
因为字典是无序的.最好根据key值删除对应的value值
4.clear清空字典内容
6.字典的修改与查看
查看字典里所有的key值
查看字典里所有的value值
通过字典的key获取对应的value值
students = {
'user1': [100, 100, 100],
'user2': [98, 100, 100],
'user3': [100, 89, 100],
}
print(students['user1'])
print(students['user4']) # KeyError: 'user4', 因为key值在字典中不存在
通过get方法获取value值(重要)
如果key存在,获取对应的value值; 反之, 返回默认值(如果不指定,默认返回的是None)
print(students.get('user1')) # [100, 100, 100]
print(students.get('user4', 'no user')) # 指定默认值为'no user'
print(students.get('user5')) #None,因为没有指定默认值
字典的遍历(2种方法)
items方法会返回一个键/值对列表 [(key1, value1),(key2, value2)],在for循环中使用items通常是迭代处理字典的首选技术,这样可以直接利用两个循环变量访问键和值。
7.字典的应用
- 1.列表去重 fromkeys()方法
列表的去重之前介绍了两种方法
1.循环+成员操作符(if not in)
2.将列表转换为集合
第三种列表去重的方法是通过字典的方式去重, 因为字典的key值是不能重复的。
li = [1, 2, 3, 4, 65, 1, 2, 3]
print({}.fromkeys(li).keys()) #fromkeys()创建了值为None的字典,再用.keys()去吃key值
- 2.switch语句的实现
python中不支持switch语句,但是可以使用字典实现switch语句。
grade = input('>>')
grade_dict = {
'A':'优秀',
'B':'良好',
'C':'及格',
'D':'不及格'
}
if grade in grade_dict:
print(grade_dict[grade])
else:
print('无效的成绩')
但是上面的if-else语句可以使用get()方法代替。
grade = input('>>')
grade_dict = {
'A':'优秀',
'B':'良好',
'C':'及格',
'D':'不及格'
}
print(grade_dict.get(grade,'无效的成绩'))
8.字典的练习
1)
##重复的单词: 此处认为单词之间以空格为分隔符, 并且不包含,和.;
1. 用户输入一句英文句子;
2. 打印出每个单词及其重复的次数;
words = input("please input an english sentence:\n").strip()
lst = words.split()
dic_num = {}
for i in lst:
if i in dic_num:
dic_num[i] += 1
else:
dic_num[i] = 1
for key in dic_num:
print(key,dic_num[key])
2)
##数字重复统计:
1). 随机生成1000个整数;
2). 数字的范围[20, 100],
3). 升序输出所有不同的数字及其每个数字重复的次数;
import random
a = [random.randint(20,100) for i in range(1000)]
b = set(a)
print("数字\t\t重复次数")
for i in b:
print("%d\t\t\t%d" %(i,a.count(i)))
3)
# 1. 随机生成100个卡号;
# 卡号以6102009开头, 后面3位依次是 (001, 002, 003, 100),
# 2. 生成关于银行卡号的字典, 默认每个卡号的初始密码为"redhat";
# 3. 输出卡号和密码信息, 格式如下:
卡号 密码
6102009001 000000
card_ids = [] //存储所有卡号列表,也可以通过集合来存储
for i in range(100): //生成100个卡号
s = '6102009%.3d' %(i+1) //%.3d代表这个整型数占3位 eg:1--->001
card_ids.append(s) //将每次生成的卡号都加入到列表中
card_ids_dict = {}.fromkeys(card_ids,'redhat')
print('卡号\t\t\t\t\t密码')
for key in card_ids_dict:
print('%s\t\t\t%s' %(key,card_ids_dict[key]))