python专区--容器详解(字典与集合)

容器详解

字典

字典的定义 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,例如:列表和字典;
      • 不可变对象可以作为字典的键,例如:数值,字符串,和元组;

练习:模拟用户登录信息系统

需求

  1. 支持新用户注册(添加),新用户名和密码注册到字典中
  2. 支持老用户登陆(查询),用户名和密码正确提示登陆成功
  3. 主程序通过循环询问,进行何种操作,根据用户的选择,执行注册或是登陆操作
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)}

集合与字典虽然都是用{}括号,但字典内部是键值对,而集合内部直接是值。

集合类型操作符

  • 集合支持用 innot 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)

猜你喜欢

转载自blog.csdn.net/m0_52508197/article/details/127194862