Python入门之字典

1. 字典的初识

1.1 字典核心定义

字典(Dictionary)是 Python 中以「键值对(key-value)」 存储数据的映射型数据结构,通过键(key) 快速定位值(value),是 Python 最常用的数据结构之一。

  • 语法:用大括号 {} 包裹,键值对用 : 分隔,多个键值对用 , 分隔
  • 规则:键必须唯一且不可变(字符串 / 数字 / 元组),值可任意类型(字符串、列表、字典等)

1.2 字典与列表对比

列表靠索引定位数据,含义模糊;字典靠定位数据,语义清晰。

# 列表:按索引存储,无法直观知道每个数据的含义
info_list = ["yuan", 18, 185, 70]
# 字典:按键值对存储,name/age/height明确表示数据含义
info_dict = {"name": "yuan", "age": 18, "height": 185, "weight": 70}
# 查看数据类型,输出<class 'dict'>
print(type(info_dict))

1.3 通俗类比:新华字典

字典就像我们用的新华字典:

  • 音节表(查字索引)= 字典的键(key)
  • 对应的汉字 = 字典的值(value)
  • 查字靠音节,查字典靠键,查询效率极高

2. 字典的存储原理(哈希 / 散列表)

2.1 哈希(Hash)基础

哈希是将任意长度输入,通过算法转为固定长度散列值的函数,是字典实现高效查询的核心。

2.2 字典的存储结构

字典本质是散列表(稀疏数组),每个存储单元叫bucket,包含两部分:

  • 键对象的引用
  • 值对象的引用
  • 通过偏移量直接定位 bucket

2.3 键值对存储过程

# 1. 创建空字典
d = {}

# 2. 向字典添加键值对:key="name",value="yuan"
d["name"] = "yuan"

# 3. 计算key的哈希值,并转为二进制形式
print(bin(hash("name")))
0b100000010000100110101111111010000110111010101111110001000101111
-0b11110101000101000110100000000001000100111100110000010110100010

存储步骤:

  • 计算 key 的哈希值 → 取二进制最后 3 位作为偏移量
  • 检查对应偏移量的 bucket 是否为空
  • 为空则存入;不为空则顺延下一个偏移量,直到找到空 bucket

2.4 字典查询过程

# 方式1:直接通过键查询(键不存在会直接报错)
d["name"]
print(d["name"])
KeyError: 'name'

# 方式2:get()安全查询(键不存在返回None,不报错)
d.get("name")
print(d.get("name"))
None

查询步骤:

  • 计算目标 key 的哈希值 → 取偏移量定位 bucket
  • 对比 bucket 中 key 的哈希值与目标 key
  • 一致则返回值;不一致则顺延,无结果返回 None

2.5 哈希值每次不同的原因

Python 每次启动会随机生成哈希种子,防止哈希碰撞攻击,提升数据安全性。

d = {}
d["name"] = "yuan"

计算key的哈希值,并转为二进制形式
print(bin(hash("name")))
0b1101100101011000100110001100011100110110101001101101101010  #第一次
-0b11110101000101000110100000000001000100111100110000010110100010  #第二次

3. 字典的核心特点

  • 无序性:无索引,靠键访问(Python3.7 + 默认保留插入顺序)
  • 键的特性:唯一、不可变,不可重复
  • 可变性:支持增 / 删 / 改键值对,动态调整数据

4. 字典的基本操作

4.1 创建字典

# 直接用{}创建字典
gf = {"name":"高圆圆","age":32}

# 查看字典中键值对的总数量
print(len(gf))  # 输出:2

4.2 查询键值

gf = {"name":"张三","age":33}
# 通过键直接取值(键不存在会报错)

print(gf["name"])  # 输出:张三
print(gf["age"])   # 输出:33

4.3 添加 / 修改键值对

  • 已存在修改对应值
  • 不存在添加新键值对
gf = {"name":"张三","age":33}
# 键age已存在,执行修改操作
gf["age"] = 29
print(gf) 
# 输出结果
{'name': '张三', 'age': 29}

# 键gender不存在,执行添加操作
gf["gender"] = "female"
print(gf)  
# 输出结果
{'name': '张三', 'age': 29, 'gender': 'female'}

4.4 删除键值对

gf = {"name":"张三","age":32,"gender":"female"}
# 删除指定键值对:删除age键
del gf["age"]
print(gf)  
# 输出结果
{'name': '张三', 'gender': 'female'}

# 删除整个字典变量(删除后无法访问)
del gf
print(gf)  
# 输出结果
报错:name 'gf' is not defined

4.5 删除键值对

gf = {"name":"张三","age":32}
# 判断"weight"是否为字典的键
print("weight" in gf)  # 输出:False

4.6 循环遍历字典

gf = {"name":"张三","age":32}
# 遍历字典所有键,通过键获取对应值
for key in gf:
    print(key, gf[key])

# 输出结果:
# name 张三
# age 32

5. 字典常用内置方法

方法名作用
update()批量添加 / 修改键值对
pop()删除指定键,返回对应值
popitem()删除最后一个键值对
clear()清空字典所有数据
get()安全取值,不存在返回 None
keys()获取所有键
values()获取所有值
items()获取所有键值对(元组)
dict.fromkeys()批量创建键,统一赋值

5.1 方法案例

# 初始化基础字典
d = {"name":"yuan","age":18}

# 1. update():批量修改+添加键值对
d.update({"age": 19,"height":"190cm"})
print(d)  # {'name': 'yuan', 'age': 19, 'height': '190cm'}

# 2. pop():删除指定键"age",返回被删除的值19
d.pop("age")
print(d)  # {'name': 'yuan', 'height': '190cm'}

# 3. popitem():删除最后一个键值对
d.popitem()
print(d)  # {'name': 'yuan'}

# 4. clear():清空字典,变为空字典
d.clear()
print(d)  # {}

# 重新初始化字典
d = {"name":"yuan","age":18}
# 5. get():安全查询,键不存在返回None
print(d.get("name"))  # yuan

# 6. keys():获取字典所有键
print(d.keys())  # dict_keys(['name', 'age'])

# 7. values():获取字典所有值
print(d.values())  # dict_values(['yuan', 18])

# 8. items():获取所有键值对(元组形式)
print(d.items())  # dict_items([('name', 'yuan'), ('age', 18)])

# 9. dict.fromkeys():批量创建键,统一赋值60
knowledge = ['语文', '数学', '英语']
scores = dict.fromkeys(knowledge, 60)
print(scores)  # {'语文': 60, '数学': 60, '英语': 60}

# 综合演示
gf = {"name": "张三", "age": 32}
# get()安全取值
print(gf.get("name"))  # 张三
# update()修改年龄+添加体重
gf.update({"age": 18, "weight": "50kg"})
print(gf)  # {'name': '张三', 'age': 18, 'weight': '50kg'}
# pop()删除weight键,接收被删除的值
ret = gf.pop("weight")
print(gf)  # {'name': '张三', 'age': 18}
# items()遍历键值对
for k, v in gf.items():
    print(k, v)

6. 列表与字典嵌套

6.1 案例 1:字典值为列表(引用传递)

# 定义普通列表
l1 = [3, 4, 5]
# 定义字典,c键指向列表l1(引用传递,共享同一份数据)
d1 = {"a": 1, "b": 2, "c": l1}
# 向原列表添加元素,字典中的c值同步变化
l1.append(6)
print(d1)  # {'a': 1, 'b': 2, 'c': [3, 4, 5, 6]}

# 修改字典中c的第一个元素,原列表同步变化
d1["c"][0] = 300
print(l1)  # [300, 4, 5, 6]

6.2 案例 2:字典嵌套字典

# 定义内层字典
d2 = {"x": 10, "y": 20}
# 定义外层字典,c键指向内层字典d2
d3 = {"a": 1, "b": 2, "c": d2}
# 向内层字典添加键值对,外层字典同步更新
d2["z"] = 30
print(d3)  # {'a': 1, 'b': 2, 'c': {'x': 10, 'y': 20, 'z': 30}}

# 修改内层字典的x值(两种方式等价)
d3["c"].update({"x": 100})
print(d2)  # {'x': 100, 'y': 20, 'z': 30}

# 重新赋值c键,断开与内层字典的引用
d3["c"] = 3
print(d3)  # {'a': 1, 'b': 2, 'c': 3}

6.3 案例 3:列表嵌套字典

# 定义基础字典
d4 = {"x": 10, "y": 20}
# 定义列表,第三个元素为字典d4
l2 = [1, 2, d4]
# 通过列表操作,删除字典d4中的y键
l2[2].pop("y")
print(d4)  # {'x': 10}

7. 实战:客户信息管理系统

7.1 案例 1:列表嵌套字典(按姓名操作)

# 初始化客户列表:列表中每个元素是【客户字典】
customers = [
    {"name": "Alice", "age": 25, "email": "alice@example.com"},
    {"name": "Bob", "age": 28, "email": "bob@example.com"}
]

# 无限循环,实现菜单功能
while True:
    # 打印功能菜单
    print("""
           1. 添加客户
           2. 删除客户
           3. 修改客户
           4. 查询一个客户
           5. 查询所有客户
           6. 退出
        """)
    # 获取用户输入的选项
    choice = input("请输入您的选择:")

    # 1. 添加客户
    if choice == "1":
        # 获取用户输入的客户信息
        name = input("请输入添加客户的姓名:")
        age = input("请输入添加客户的年龄:")
        email = input("请输入添加客户的邮箱:")
        # 封装为客户字典
        new_customer = {"name": name, "age": age, "email": email}
        # 添加到客户列表
        customers.append(new_customer)
        print(f"添加客户{name}成功!")

    # 2. 删除客户
    elif choice == "2":
        del_name = input("请输入删除客户的姓名:")
        flag = False  # 标记是否找到客户
        # 遍历客户列表
        for customer in customers:
            if customer["name"] == del_name:
                customers.remove(customer)
                print(f"客户{del_name}删除成功!")
                flag = True
                break
        if not flag:
            print(f"客户{del_name}不存在!")

    # 3. 修改客户
    elif choice == "3":
        update_name = input("请输入修改客户的姓名:")
        # 获取新信息
        name = input("请输入新姓名:")
        age = input("请输入新年龄:")
        email = input("请输入新邮箱:")
        # 遍历匹配并修改
        for customer in customers:
            if customer["name"] == update_name:
                customer.update({"name": name, "age": age, "email": email})
                break
        print("客户信息修改完成!")

    # 4. 查询单个客户
    elif choice == "4":
        query_name = input("请输入要查询的客户姓名:")
        for customer in customers:
            if customer["name"] == query_name:
                print(f"姓名:{customer.get('name')},年龄:{customer.get('age')},邮箱:{customer.get('email')}")
                break

    # 5. 查询所有客户
    elif choice == "5":
        if customers:
            for customer in customers:
                print(f"姓名:{customer.get('name'):10},年龄:{customer.get('age')},邮箱:{customer.get('email')}")
        else:
            print("当前无客户信息!")

    # 6. 退出程序
    elif choice == "6":
        print("退出程序!")
        break

    # 无效输入
    else:
        print("输入格式错误!")

7.2 案例 2:字典嵌套字典(按 ID 操作,效率更高)

# 初始化:外层key=客户ID,value=客户字典(按ID查询更快)
customers = {
    1001: {"name": "Alice", "age": 25, "email": "alice@example.com"},
    1002: {"name": "Bob", "age": 28, "email": "bob@example.com"}
}

while True:
    print("""
           1. 添加客户
           2. 删除客户
           3. 修改客户
           4. 查询一个客户
           5. 查询所有客户
           6. 退出
        """)
    choice = input("请输入您的选择:")

    # 1. 添加客户
    if choice == "1":
        cid = int(input("请输入客户ID:"))
        if cid in customers:
            print("该ID已存在!")
        else:
            name = input("请输入姓名:")
            age = input("请输入年龄:")
            email = input("请输入邮箱:")
            customers[cid] = {"name": name, "age": age, "email": email}
            print(f"添加客户{name}成功!")

    # 2. 删除客户(按ID删除,O(1)效率)
    elif choice == "2":
        cid = int(input("请输入删除的客户ID:"))
        if cid in customers:
            customers.pop(cid)
            print(f"删除{cid}成功!")
        else:
            print("ID不存在!")

    # 3. 修改客户
    elif choice == "3":
        cid = int(input("请输入修改的客户ID:"))
        if cid in customers:
            name = input("新姓名:")
            age = input("新年龄:")
            email = input("新邮箱:")
            customers[cid].update({"name": name, "age": age, "email": email})
            print(f"{cid}修改成功!")
        else:
            print("ID不存在!")

    # 4. 查询单个客户
    elif choice == "4":
        cid = int(input("请输入查询的客户ID:"))
        if cid in customers:
            customer = customers[cid]
            print(f"姓名:{customer.get('name')},年龄:{customer.get('age')},邮箱:{customer.get('email')}")
        else:
            print("ID不存在!")

    # 5. 查询所有客户
    elif choice == "5":
        if customers:
            for cid,customer in customers.items():
                print(f"ID:{cid},姓名:{customer.get('name'):10},年龄:{customer.get('age')},邮箱:{customer.get('email')}")
        else:
            print("无客户信息!")

    # 6. 退出
    elif choice == "6":
        print("退出程序!")
        break

    else:
        print("输入错误!")

原创内容声明

作者 山海
来源平台 山海运维

本文为原创内容,版权归作者所有,未经授权禁止任何形式转载

(0)

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注