Python字典:键值对、get()方法、defaultdict,附通讯录实战


Python字典:键值对、get()方法、defaultdict,附通讯录实战

上一篇文章讲了列表,列表是按顺序存放数据的。但有时候我们不需要顺序,而是需要"按名字找电话"这种"键值对应"的关系------这时候就要用字典了。


一句话概括

这篇文章解决一个问题:学会Python字典的键值对操作,理解get()方法和defaultdict的用法。


什么是字典

字典用花括号 {} 表示,里面存的是键值对(key-value pairs):

python 复制代码
# 键是字符串,值是数字
ages = {"小明": 18, "小红": 20, "小李": 22}

# 键是字符串,值是字符串
person = {"name": "张三", "city": "北京", "job": "工程师"}

# 键可以是多种类型
mixed = {1: "one", "two": 2, False: "false"}

# 列表不能作为键(不可哈希)
# 错误:{[1,2]: "value"}  # TypeError
# 正确:(1,2)可以作为键

创建字典

python 复制代码
# 直接创建
person = {"name": "张三", "age": 18, "city": "北京"}

# 用 dict() 函数
person = dict(name="张三", age=18, city="北京")

# 用 zip() 合并两个列表
keys = ["name", "age", "city"]
values = ["张三", 18, "北京"]
person = dict(zip(keys, values))  # {'name': '张三', 'age': 18, 'city': '北京'}

# 空字典
empty = {}

查:访问字典

通过键访问值

python 复制代码
person = {"name": "张三", "age": 18, "city": "北京"}

print(person["name"])  # 张三
print(person["age"])   # 18

注意 :如果键不存在,会报 KeyError

python 复制代码
print(person["job"])  # KeyError: 'job'

安全访问:用 get()

python 复制代码
person = {"name": "张三", "age": 18}

print(person.get("name"))     # 张三
print(person.get("job"))     # None(不报错,返回None)
print(person.get("job", "未知"))  # 未知(键不存在时返回默认值)

建议 :所有字典访问优先用 get(),避免 KeyError。


改:添加和修改

python 复制代码
person = {"name": "张三", "age": 18}

# 添加新键值对
person["city"] = "北京"   # {'name': '张三', 'age': 18, 'city': '北京'}

# 修改已存在的值
person["age"] = 19       # {'name': '张三', 'age': 19, 'city': '北京'}

删:删除键值对

python 复制代码
person = {"name": "张三", "age": 18, "city": "北京"}

# pop():删除指定键,返回值
age = person.pop("age")  # 删除'age'键,返回18,person={'name': '张三', 'city': '北京'}

# del:删除指定键(不返回值)
del person["city"]  # person={'name': '张三'}

# popitem():删除最后一个键值对
person = {"name": "张三", "age": 18, "city": "北京"}
key, value = person.popitem()  # ('city', '北京'),person={'name': '张三', 'age': 18}

# clear():清空字典
person.clear()  # {}

遍历字典

python 复制代码
person = {"name": "张三", "age": 18, "city": "北京"}

# 遍历键
for key in person:
    print(key)
# 输出:name, age, city

# 遍历值
for value in person.values():
    print(value)
# 输出:张三, 18, 北京

# 遍历键值对
for key, value in person.items():
    print(f"{key}: {value}")
# 输出:name: 张三, age: 18, city: 北京

# 字典推导式
squares = {x: x**2 for x in range(5)}  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

defaultdict:默认值字典

这是字典的一个进阶用法,来自 collections 模块。

普通字典的问题

python 复制代码
# 普通字典
word_count = {}

# 统计单词出现次数
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]

for word in words:
    if word in word_count:
        word_count[word] += 1
    else:
        word_count[word] = 1

print(word_count)  # {'apple': 3, 'banana': 2, 'cherry': 1}

每次都要判断键是否存在,很麻烦。

用 defaultdict 简化

python 复制代码
from collections import defaultdict

word_count = defaultdict(int)  # 默认值是0

words = ["apple", "banana", "apple", "cherry", "banana", "apple"]

for word in words:
    word_count[word] += 1  # 如果键不存在,会自动初始化为0

print(dict(word_count))  # {'apple': 3, 'banana': 2, 'cherry': 1}

defaultdict(int) 的意思是:如果键不存在,自动创建并赋值为 int() 的默认值(即0)。

defaultdict 的其他默认值类型

python 复制代码
from collections import defaultdict

# 默认值是0
dd_int = defaultdict(int)

# 默认值是空列表
dd_list = defaultdict(list)
dd_list["fruits"].append("apple")  # {'fruits': ['apple']}

# 默认值是空字典
dd_dict = defaultdict(dict)

# 默认值是集合
dd_set = defaultdict(set)
dd_set["colors"].add("red")  # {'colors': {'red'}}

实战练习:词频统计

用字典做一个中英文词频统计工具:

python 复制代码
from collections import defaultdict
import re

def count_words(text):
    """统计文本中单词出现次数"""
    # 提取单词(只保留字母,忽略标点符号和数字)
    words = re.findall(r'[a-zA-Z]+', text.lower())
    
    # 用 defaultdict 统计
    word_count = defaultdict(int)
    for word in words:
        word_count[word] += 1
    
    return word_count

def show_top_words(word_count, n=10):
    """显示前n个最高频的词"""
    # 按出现次数排序
    sorted_words = sorted(word_count.items(), key=lambda x: x[1], reverse=True)
    
    print(f"\n{'排名':<6}{'单词':<15}{'出现次数':<10}")
    print("-" * 30)
    for i, (word, count) in enumerate(sorted_words[:n], 1):
        print(f"{i:<6}{word:<15}{count:<10}")

# 测试
text = """
Python is a great programming language. Python is used for web development, 
data science, artificial intelligence, and many more. Python has a simple 
syntax that makes it easy to learn and read. Many people love Python.
"""

result = count_words(text)
show_top_words(result)

实战练习:多层嵌套字典

用字典模拟一个班级管理系统:

python 复制代码
# 班级数据:多层嵌套字典
classroom = {
    "class_a": {
        "teacher": "李老师",
        "students": {
            "001": {"name": "小明", "math": 95, "english": 88},
            "002": {"name": "小红", "math": 87, "english": 92},
            "003": {"name": "小李", "math": 78, "english": 85},
        }
    },
    "class_b": {
        "teacher": "王老师",
        "students": {
            "001": {"name": "小刚", "math": 91, "english": 79},
            "002": {"name": "小芳", "math": 85, "english": 90},
        }
    }
}

# 查询:class_a的小红数学成绩
math_score = classroom["class_a"]["students"]["002"]["math"]
print(f"小红的数学成绩:{math_score}")  # 87

# 统计:所有学生的平均数学成绩
all_math_scores = []
for cls in classroom.values():
    for student in cls["students"].values():
        all_math_scores.append(student["math"])

avg_math = sum(all_math_scores) / len(all_math_scores)
print(f"班级平均数学成绩:{avg_math:.1f}")  # 87.2

常见问题FAQ

Q1:字典的键有什么限制?

字典的键必须是**可哈希(hashable)**的对象:

  • 可以:字符串、数字、元组、布尔值
  • 不可以:列表、字典、集合
python 复制代码
# 合法
d = {(1, 2): "tuple key"}
d = {"string": "value"}
d = {1: "int key"}

# 非法
d = {[1, 2]: "list key"}  # 报错!列表不可哈希

Q2:字典和列表怎么选?

场景 用什么
按键快速查找 字典
需要保持顺序 字典(Python 3.7+有序)或列表
按索引访问 列表
存储同类型连续数据 列表
一对一映射关系 字典

Q3:怎么判断键是否在字典里?

python 复制代码
person = {"name": "张三", "age": 18}

# 用 in
if "name" in person:
    print("有name键")

# 用 get()(更安全)
if person.get("name"):
    print("有name键且值不为空/0/False")

写在最后

字典是Python里最实用的数据结构之一:

  • 键值对应,查找O(1)复杂度
  • defaultdict 简化默认值处理
  • 可以多层嵌套,模拟复杂数据结构

下一篇文章:Python 集合与元组,去重利器与不可变列表。


参考资料

相关推荐
liuyao_xianhui1 小时前
优选算法_翻转链表_头插法_C++
开发语言·数据结构·c++·算法·leetcode·链表·动态规划
wanhengidc1 小时前
跨境云手机适用于哪些场景
大数据·运维·服务器·数据库·科技·智能手机
happy_baymax1 小时前
三电平矢量表达式MATLAB实现
开发语言·matlab
xyq20242 小时前
jEasyUI 创建 XP 风格左侧面板
开发语言
赫瑞2 小时前
Java中的最长公共子序列——LCS
java·开发语言
于先生吖2 小时前
零基础开发国际版同城出行平台 JAVA 顺风车预约系统实战教学
java·开发语言
代码雕刻家2 小时前
2.22.StringBuffer类的常见用法、
java·开发语言
七夜zippoe2 小时前
区块链开发:从智能合约到DApp
python·区块链·智能合约·开发·dapp
hhhjllhj2 小时前
如何用关键词优化报表提升网站流量?
python·搜索引擎·facebook