目录
容器详解
字典
字典的定义 dict
dictionary
(字典) 是 除列表以外Python
之中 最灵活 的数据类型- 字典同样可以用来 存储多个数据
- 通常用于存储 描述一个
物体
的相关信息
- 通常用于存储 描述一个
- 和列表的区别
- 列表 是 有序 的对象集合
- 字典 是 无序 的对象集合
- 字典用
{}
定义 - 字典使用 键值对 存储数据,键值对之间使用
,
分隔- 键
key
是索引 - 值
value
是数据 - 键 和 值 之间使用
:
分隔 - 键必须是唯一的
- 值 可以取任何数据类型,但 键 只能使用 字符串、数字或 元组
- 键
基本操作
创建字典
- 通过
{}
操作符创建字典
案例
dict01 = {
"name": "zhangsan", "age": 18}
常见方法
访问字典:查询
字典是映射类型,意味着它没有下标,访问字典中的值需要使用相应的键
通过键 (key)
,访问字典
info = {
"age":12, "status":True, "name":"nfx"}
print(dict01["name"]) # 获取 name 对应的 value
print("name" in dict01) # 判断 name 是不是字典的 key
# 根据 name 为键去 info 字典中获取对应的值,如果不存在则返回 None,存在则返回值
info = {
"age":12, "status":True,"name":"nfx"}
data = info.get("name", None)
print(data) # 输出:nfx
# 根据 score 为键去 info 字典中获取对应的值,如果不存在则返回 "没有成绩",存在则返回值
data = info.get("score", "没有成绩")
print(data) # 输出:"没有成绩"
获取所有的键
通过 字典对象.keys()
获取
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
data = info.keys() # 获取字典的所有的键,返回一个"高仿的列表",存放的都是字典中的key。
print(data) # 输出:dict_keys(['age', 'status', 'name', 'email'])
遍历:分别打印出每个 key
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
for ele in info.keys():
print(ele) # 打印出每个 key
print(info[ele]) # 根据 key 获取并打印对应的 value
获取所有的值
通过 字典对象.values()
获取
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
data = info.values()
print(data) # 输出:dict_values([12, True, 'nfx', '[email protected]'])
遍历:分别打印出每个 value
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
for val in info.values():
print(val) # 输出:dict_values([12, True, 'nfx', '[email protected]'])
获取所有键值对
通过 字典对象.items()
获取
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
data = info.items()
print(data) # 输出 dict_items([('age', 12), ('status', True), ('name', 'nfx'), ('email', '[email protected]')])
遍历:分别打印出每个 k:v
对
for item in info.items():
print(item) # item是一个元组 (键,值)
更新键值
通过 字典对象.update()
修改或添加
info = {
"age":12, "status":True}
info.update({
"age":14,"name":"nfx"}) # info中没有的键直接添加;有的键则更新值
print(info) # 输出:{"age":14, "status":True,"name":"nfx"}
或者通过 字典对象[key]
修改或添加
info = {
"age":12, "status":True}
info["name"] = "nfx" # info中没有的键直接添加
info["age"] = 18 # info中有的键则更新值
print(info) # {"age":18, "status":True,"name":"nfx"}
删除操作
pop()
,弹出指定键对应的元素并将弹出的元素返回
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
info.pop("age")
print(info) # {'status': True, 'name': 'nfx', 'email': '[email protected]'}
del:删除指定的键值对,不返回数据
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
del info["age"]
print(info) # {'status': True, 'name': 'nfx', 'email': '[email protected]'}
清空字典:clear()
info = {
"age":12, "status":True, "name":"nfx","email":"[email protected]"}
info.clear()
print(info) # {}
其他
字典相关函数
-
len():返回字典中元素的数目
-
hash():不是为字典设计,可以判断对象是否可以作为字典的键
- hash() 可以判断对象是否可以作为字典的键:
- 可变对象不能作为字典的key,例如:列表和字典;
- 不可变对象可以作为字典的键,例如:数值,字符串,和元组;
- hash() 可以判断对象是否可以作为字典的键:
练习:模拟用户登录信息系统
需求
- 支持新用户注册(添加),新用户名和密码注册到字典中
- 支持老用户登陆(查询),用户名和密码正确提示登陆成功
- 主程序通过循环询问,进行何种操作,根据用户的选择,执行注册或是登陆操作
userdb = {
} # 定义一个字典,用于存储用户名和密码
def register():
username = input('用户名: ').strip() # strip()删除字串两边空白
# 当username不为空,并且不在字典userdb中时才会创建密码,写入用户信息到字典
if username and username not in userdb:
password = input('密码: ')
userdb[username] = password
# 如果username为空值,并且在userdb中,执行print()
else:
print('您必须输入用户名,或用户名已存在')
def login():
username = input('用户名: ')
password = input('密码: ')
#if (username not in userdb) or (userdb[username] != password):
# 判断字典userdb中,是否存在用户username,不存在则userdb.get()返回空值,登录失败
# 如果username用户存在,对应的值是否和password相等,不相等则登录失败
if userdb.get(username) != password:
print('登录失败')
else:
print('登录成功')
def show_menu():
# 定义变量prompt,提示用户输入选项
prompt = """(0) 注册
(1)登陆
(2)退出
请做出选择(0/1/2): """
while 1: # while循环,让用户可以无限重复操作
choice = input(prompt) # 提示用户输入信息
if choice not in ['0', '1', '2']:
print('无效的输入,请重试。')
continue # 结束此次循环,直接开始下次循环
if choice == '0': # 用户选择0
register()
elif choice == '1': # 用户选择1
login()
else: # 用户选择2,打印bye,退出while循环
print('Bye-bye')
break # 直接退出while循环
if __name__ == '__main__':
show_menu()
集合 set
- 集合与元组和列表相似都用于做容器,在内部可以放一些子元素
- 集合有三特殊特点:
子元素不重复
、子元素必须可哈希
、无序
。
提示:目前可哈希的数据类型 int/str/tuple
;不可哈希的类型 dict/list/set
。
常用方法
创建集合
set01 = {
1, 2, 99, 18}
set02 = {
"nfx", "Alex", "老妖", "Egon"}
set03 = {
1, True, "world", (11, 22, 33)}
集合与字典虽然都是用{}
括号,但字典内部是键值对,而集合内部直接是值。
集合类型操作符
-
集合支持用
in
和not in
操作符检查成员 -
能够通过
len()
检查集合大小 -
能够使用
for
迭代集合成员 -
不能取切片,没有键
set01 = {
1, 2, 3, 4}
print(1 in set01)
print(len(set01))
for i in set01:
print(i)
添加元素 add()
data = {
"刘嘉玲", '关之琳', "王祖贤"}
data.add("郑裕玲")
print(data)
data = set()
data.add("周杰伦")
data.add("林俊杰")
print(data)
删除元素
remove()
- 从集合中移除一个元素;它 必须 是一个成员。
- 如果元素不是成员,则引发 KeyError。
data = {
"刘嘉玲", '关之琳', "王祖贤"}
data.remove("刘嘉玲")
print(data)
交集
图例
s1 = {
"刘能", "赵四", "⽪⻓⼭"}
s2 = {
"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s1 & s2 # 方式一:取两个集合的交集
s4 = s1.intersection(s2) # 方式二:取两个集合的交集
print(s3, s4)
并集
图例
s1 = {
"刘能", "赵四", "⽪⻓⼭"}
s2 = {
"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s1 | s2 # 方式一:取两个集合的并集
s4 = s1.union(s2) # 方式二:取两个集合的并集
print(s3, s4)
差集
图例
s1 = {
"刘能", "赵四", "⽪⻓⼭"}
s2 = {
"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s1 - s2 # 方式一:差集,s1中有且s2中没有的值
s4 = s1.difference(s2) # 方式二:差集,s1中有且s2中没有的值
print(s3, s4)
图例
s1 = {
"刘能", "赵四", "⽪⻓⼭"}
s2 = {
"刘科⻓", "冯乡⻓", "⽪⻓⼭"}
s3 = s2 - s1 # 方式一:差集,s2中有且s1中没有的值
s4 = s2.difference(s1) # 方式二:差集,s2中有且s1中没有的值
print(s3, s4)
其他
-
其他类型如果想要转换为集合类型,可以通过
set
进行转换,并且如果数据有重复则 自动去重。 -
提示:
int/list/tuple/dict
都可以转换为集合。
v1 = [11, 22, 33, 11, 3, 99, 22]
v2 = set(v1)
print(v2) # {11,22,33,3,99}
print(list(v2)) # 再将set转换成list类型
练习:比较文件内容
需求
- 有两个文件:a.log 和 b.log
- 两个文件中有大量重复内容
- 取出只有在 b.log 中存在的行
# 定义变量,指定要操作的文件路径
fname1 = '/opt/a.log'
fname2 = '/opt/b.log'
# 将对象fobj1转换为集合类型(集合中的元素无序排列,且不会重复)
with open(fname1, mode="r") as fobj1:
aset = set(fobj1.readlines())
# 将对象fobj2转换为集合类型(集合中的元素无序排列,且不会重复)
with open(fname2, mode="r") as fobj2:
bset = set(fobj2.readlines())
print(bset - aset)