Python 容器数据类型

Python 容器数据类型

目录

  • [列表 list](#列表 list "#%E5%88%97%E8%A1%A8-list")
  • [元组 tuple](#元组 tuple "#%E5%85%83%E7%BB%84-tuple")
  • [字典 dict](#字典 dict "#%E5%AD%97%E5%85%B8-dict")
  • [集合 set](#集合 set "#%E9%9B%86%E5%90%88-set")
  • [字符串 str](#字符串 str "#%E5%AD%97%E7%AC%A6%E4%B8%B2-str")
  • 容器操作通用方法
  • 综合实战

列表 list

列表是 Python 中最常用的可变有序序列。

创建列表

python 复制代码
# 空列表
empty_list = []
empty_list = list()

# 初始化列表
fruits = ["苹果", "香蕉", "橙子"]
numbers = [1, 2, 3, 4, 5]
mixed = [1, "hello", 3.14, True, [1, 2]]

# 使用 list() 转换
string_list = list("hello")  # ['h', 'e', 'l', 'l', 'o']
range_list = list(range(5))  # [0, 1, 2, 3, 4]

访问元素

python 复制代码
fruits = ["苹果", "香蕉", "橙子", "葡萄", "西瓜"]

# 正向索引(从 0 开始)
print(fruits[0])   # 苹果
print(fruits[2])   # 橙子

# 负向索引(从 -1 开始)
print(fruits[-1])  # 西瓜
print(fruits[-2])  # 葡萄

# 切片 [start:stop:step]
print(fruits[1:3])     # ['香蕉', '橙子']
print(fruits[:3])      # ['苹果', '香蕉', '橙子']
print(fruits[2:])      # ['橙子', '葡萄', '西瓜']
print(fruits[::2])     # ['苹果', '橙子', '西瓜']
print(fruits[::-1])    # ['西瓜', '葡萄', '橙子', '香蕉', '苹果'](反转)

修改列表

python 复制代码
fruits = ["苹果", "香蕉", "橙子"]

# 修改元素
fruits[1] = "芒果"
print(fruits)  # ['苹果', '芒果', '橙子']

# 添加元素
fruits.append("葡萄")           # 末尾添加
fruits.insert(1, "草莓")        # 指定位置插入
fruits.extend(["西瓜", "哈密瓜"]) # 扩展列表

print(fruits)  # ['苹果', '草莓', '芒果', '橙子', '葡萄', '西瓜', '哈密瓜']

# 删除元素
fruits.remove("芒果")    # 删除指定值
del fruits[0]            # 删除指定索引
popped = fruits.pop()    # 删除并返回最后一个元素
popped = fruits.pop(1)   # 删除并返回指定索引的元素

print(fruits)
print(f"弹出: {popped}")

列表常用方法

python 复制代码
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5]

# 查询
print(len(numbers))       # 9(长度)
print(numbers.count(5))   # 2(出现次数)
print(numbers.index(4))   # 2(首次出现的索引)

# 排序
numbers.sort()            # 原地排序
print(numbers)            # [1, 1, 2, 3, 4, 5, 5, 6, 9]

numbers.sort(reverse=True) # 降序
print(numbers)            # [9, 6, 5, 5, 4, 3, 2, 1, 1]

# 反转
numbers.reverse()
print(numbers)

# 复制
copy1 = numbers.copy()
copy2 = numbers[:]
copy3 = list(numbers)

列表推导式

python 复制代码
# 基本推导式
squares = [x ** 2 for x in range(1, 6)]
print(squares)  # [1, 4, 9, 16, 25]

# 带条件
even_squares = [x ** 2 for x in range(1, 11) if x % 2 == 0]
print(even_squares)  # [4, 16, 36, 64, 100]

# 嵌套推导式
matrix = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print(matrix)
# [[1, 2, 3], [2, 4, 6], [3, 6, 9]]

# 扁平化二维列表
flat = [num for row in matrix for num in row]
print(flat)  # [1, 2, 3, 2, 4, 6, 3, 6, 9]

列表运算

python 复制代码
# 拼接
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list3 = list1 + list2
print(list3)  # [1, 2, 3, 4, 5, 6]

# 重复
zeros = [0] * 5
print(zeros)  # [0, 0, 0, 0, 0]

# 成员检查
print(3 in list1)    # True
print(10 not in list1)  # True

元组 tuple

元组是不可变的有序序列,适合存储固定数据。

创建元组

python 复制代码
# 空元组
empty_tuple = ()
empty_tuple = tuple()

# 单元素元组(注意逗号)
single = (42,)
single = 42,

# 多元素元组
coordinates = (10, 20)
person = ("张三", 25, "北京")

# 省略括号
point = 10, 20, 30

# 使用 tuple() 转换
tuple_from_list = tuple([1, 2, 3])
tuple_from_string = tuple("abc")  # ('a', 'b', 'c')

访问元素

python 复制代码
colors = ("红", "绿", "蓝", "黄")

# 索引访问
print(colors[0])    # 红
print(colors[-1])   # 黄

# 切片
print(colors[1:3])  # ('绿', '蓝')

# ❌ 不能修改
# colors[0] = "紫"  # TypeError

元组解包

python 复制代码
# 基本解包
point = (10, 20)
x, y = point
print(f"x={x}, y={y}")

# 交换变量
a, b = 1, 2
a, b = b, a
print(f"a={a}, b={b}")  # a=2, b=1

# 星号解包
numbers = (1, 2, 3, 4, 5)
first, *middle, last = numbers
print(first)    # 1
print(middle)   # [2, 3, 4]
print(last)     # 5

# 函数返回多个值
def get_user():
    return "李四", 30, "上海"

name, age, city = get_user()

元组方法

python 复制代码
numbers = (1, 2, 3, 2, 4, 2, 5)

print(numbers.count(2))   # 3(出现次数)
print(numbers.index(3))   # 2(首次出现的索引)
print(len(numbers))       # 7(长度)

元组 vs 列表

特性 列表 元组
可变性 可变 不可变
性能 较慢 较快
内存占用 较大 较小
可作字典键
适用场景 动态数据 固定数据
python 复制代码
# 元组可以作为字典的键
locations = {
    (40.7128, -74.0060): "纽约",
    (51.5074, -0.1278): "伦敦",
}

# 元组用于保护数据不被修改
def get_constants():
    return (3.14159, 2.71828, 1.41421)

PI, E, SQRT2 = get_constants()

字典 dict

字典是键值对的无序集合(Python 3.7+ 保持插入顺序)。

创建字典

python 复制代码
# 空字典
empty_dict = {}
empty_dict = dict()

# 字面量创建
student = {
    "name": "王五",
    "age": 20,
    "major": "计算机科学",
    "scores": [90, 85, 92]
}

# dict() 构造函数
dict1 = dict(name="张三", age=25)
dict2 = dict([("a", 1), ("b", 2)])
dict3 = dict.fromkeys(["x", "y", "z"], 0)  # {'x': 0, 'y': 0, 'z': 0}

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

访问元素

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

# 通过键访问
print(student["name"])       # 张三
print(student.get("age"))    # 20
print(student.get("score"))  # None(键不存在)
print(student.get("score", 0))  # 0(提供默认值)

# ❌ 访问不存在的键会报错
# print(student["score"])  # KeyError

修改字典

python 复制代码
student = {"name": "张三", "age": 20}

# 添加/修改键值对
student["age"] = 21           # 修改
student["city"] = "上海"      # 添加
student.update({"major": "CS", "grade": "大二"})  # 批量更新

print(student)
# {'name': '张三', 'age': 21, 'city': '上海', 'major': 'CS', 'grade': '大二'}

# 删除
del student["city"]              # 删除指定键
age = student.pop("age")         # 删除并返回值
last_item = student.popitem()    # 删除并返回最后一项(LIFO)
student.clear()                  # 清空字典

遍历字典

python 复制代码
student = {"name": "李四", "age": 22, "city": "广州"}

# 遍历键
for key in student:
    print(key)

# 遍历键和值
for key, value in student.items():
    print(f"{key}: {value}")

# 只遍历值
for value in student.values():
    print(value)

# 遍历键(显式)
for key in student.keys():
    print(key)

字典方法

python 复制代码
d = {"a": 1, "b": 2, "c": 3}

# 获取所有键、值、项
print(list(d.keys()))    # ['a', 'b', 'c']
print(list(d.values()))  # [1, 2, 3]
print(list(d.items()))   # [('a', 1), ('b', 2), ('c', 3)]

# 检查键是否存在
print("a" in d)          # True
print("x" not in d)      # True

# 设置默认值
d.setdefault("d", 4)     # 如果键不存在则添加
print(d)                 # {'a': 1, 'b': 2, 'c': 3, 'd': 4}

# 合并字典(Python 3.9+)
d1 = {"a": 1, "b": 2}
d2 = {"b": 3, "c": 4}
d3 = d1 | d2             # {'a': 1, 'b': 3, 'c': 4}
d1 |= d2                 # 原地更新

嵌套字典

python 复制代码
school = {
    "class_1": {
        "teacher": "张老师",
        "students": [
            {"name": "小明", "score": 90},
            {"name": "小红", "score": 95}
        ]
    },
    "class_2": {
        "teacher": "李老师",
        "students": [
            {"name": "小刚", "score": 88},
            {"name": "小丽", "score": 92}
        ]
    }
}

# 访问嵌套数据
print(school["class_1"]["teacher"])  # 张老师
print(school["class_1"]["students"][0]["name"])  # 小明

# 遍历
for class_name, info in school.items():
    print(f"\n{class_name}:")
    print(f"  班主任: {info['teacher']}")
    print(f"  学生数: {len(info['students'])}")
    for student in info["students"]:
        print(f"    - {student['name']}: {student['score']}分")

defaultdict 和 OrderedDict

python 复制代码
from collections import defaultdict, OrderedDict

# defaultdict - 自动初始化默认值
word_count = defaultdict(int)
words = ["apple", "banana", "apple", "orange", "banana", "apple"]

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

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

# OrderedDict - 记住插入顺序(Python 3.7+ 普通字典也有序)
ordered = OrderedDict()
ordered["first"] = 1
ordered["second"] = 2
ordered["third"] = 3

集合 set

集合是无序的不重复元素集合。

创建集合

python 复制代码
# 空集合(注意:{} 是空字典)
empty_set = set()

# 初始化集合
fruits = {"苹果", "香蕉", "橙子"}
numbers = {1, 2, 3, 4, 5}

# 使用 set() 转换
set_from_list = set([1, 2, 2, 3, 3, 3])  # {1, 2, 3}(去重)
set_from_string = set("hello")  # {'h', 'e', 'l', 'o'}

# 集合推导式
squares = {x**2 for x in range(-5, 6)}
print(squares)  # {0, 1, 4, 9, 16, 25}

集合操作

python 复制代码
A = {1, 2, 3, 4, 5}
B = {4, 5, 6, 7, 8}

# 并集
print(A | B)           # {1, 2, 3, 4, 5, 6, 7, 8}
print(A.union(B))

# 交集
print(A & B)           # {4, 5}
print(A.intersection(B))

# 差集
print(A - B)           # {1, 2, 3}
print(A.difference(B))

# 对称差集(只在其中一个集合中的元素)
print(A ^ B)           # {1, 2, 3, 6, 7, 8}
print(A.symmetric_difference(B))

集合方法

python 复制代码
fruits = {"苹果", "香蕉", "橙子"}

# 添加元素
fruits.add("葡萄")
fruits.update(["西瓜", "哈密瓜"])

# 删除元素
fruits.remove("香蕉")     # 不存在会报错
fruits.discard("芒果")    # 不存在不会报错
popped = fruits.pop()     # 随机删除并返回一个元素

# 集合运算
A = {1, 2, 3}
B = {2, 3, 4}

print(A.issubset(B))      # False(A 是否是 B 的子集)
print(A.issuperset(B))    # False(A 是否是 B 的超集)
print(A.isdisjoint(B))    # False(是否有交集)

集合应用

python 复制代码
# 去重
numbers = [1, 2, 2, 3, 3, 3, 4, 5]
unique = list(set(numbers))
print(unique)  # [1, 2, 3, 4, 5]

# 查找共同元素
list1 = [1, 2, 3, 4, 5]
list2 = [4, 5, 6, 7, 8]
common = set(list1) & set(list2)
print(common)  # {4, 5}

# 检查成员(比列表快)
valid_ids = {1001, 1002, 1003, 1004, 1005}
user_id = 1003
if user_id in valid_ids:  # O(1) 时间复杂度
    print("有效用户")

frozenset(不可变集合)

python 复制代码
# 不可变集合,可作为字典的键或集合的元素
frozen = frozenset([1, 2, 3])
# frozen.add(4)  # AttributeError

# 作为字典的键
data = {
    frozenset([1, 2]): "第一组",
    frozenset([3, 4]): "第二组"
}

字符串 str

字符串是不可变的字符序列。

创建字符串

python 复制代码
# 单引号或双引号
str1 = 'Hello'
str2 = "World"

# 三引号(多行字符串)
multiline = """这是
多行
字符串"""

# 原始字符串(不转义)
path = r"C:\Users\name\file.txt"
regex = r"\d+\.\d+"

# 格式化字符串
name = "张三"
age = 25
greeting = f"你好,我叫{name},今年{age}岁"

字符串操作

python 复制代码
text = "Hello, World!"

# 长度
print(len(text))  # 13

# 索引和切片
print(text[0])     # H
print(text[-1])    # !
print(text[7:12])  # World

# ❌ 不能修改
# text[0] = 'h'  # TypeError

常用方法

python 复制代码
text = "  Hello, World!  "

# 大小写转换
print(text.upper())       # "  HELLO, WORLD!  "
print(text.lower())       # "  hello, world!  "
print(text.title())       # "  Hello, World!  "
print(text.swapcase())    # "  hELLO, wORLD!  "

# 去除空白
print(text.strip())       # "Hello, World!"
print(text.lstrip())      # "Hello, World!  "
print(text.rstrip())      # "  Hello, World!"

# 查找和替换
print(text.find("World"))     # 9(找不到返回 -1)
print(text.index("World"))    # 9(找不到抛出异常)
print(text.replace("World", "Python"))
print(text.count("l"))        # 3

# 判断
print("hello".isalpha())      # True(纯字母)
print("123".isdigit())        # True(纯数字)
print("hello123".isalnum())   # True(字母或数字)
print(" ".isspace())          # True(空白)
print("Hello".startswith("He"))  # True
print("Hello".endswith("lo"))    # True

分割和连接

python 复制代码
text = "apple,banana,orange"

# 分割
fruits = text.split(",")
print(fruits)  # ['apple', 'banana', 'orange']

text2 = "one two three"
words = text2.split()  # 默认按空白分割
print(words)  # ['one', 'two', 'three']

# 连接
result = "-".join(fruits)
print(result)  # "apple-banana-orange"

# 分区
path = "/usr/local/bin/python"
parts = path.rsplit("/", 1)
print(parts)  # ['/usr/local/bin', 'python']

字符串格式化

python 复制代码
name = "李四"
age = 30
score = 95.5

# f-string(推荐)
print(f"姓名: {name}, 年龄: {age}, 分数: {score:.1f}")

# format()
print("姓名: {}, 年龄: {}".format(name, age))
print("姓名: {n}, 年龄: {a}".format(n=name, a=age))

# % 格式化
print("姓名: %s, 年龄: %d" % (name, age))

字符串编码

python 复制代码
# UTF-8 编码
text = "你好世界"
encoded = text.encode("utf-8")
print(encoded)  # b'\xe4\xbd\xa0\xe5\xa5\xbd\xe4\xb8\x96\xe7\x95\x8c'

decoded = encoded.decode("utf-8")
print(decoded)  # 你好世界

容器操作通用方法

长度、最大最小值

python 复制代码
# 适用于列表、元组、字典、集合、字符串
lst = [3, 1, 4, 1, 5, 9]
tpl = (3, 1, 4, 1, 5, 9)
dct = {"a": 1, "b": 2, "c": 3}
st = {3, 1, 4, 1, 5, 9}
s = "hello"

print(len(lst))   # 6
print(len(tpl))   # 6
print(len(dct))   # 3
print(len(st))    # 5(去重后)
print(len(s))     # 5

print(max(lst))   # 9
print(min(lst))   # 1
print(sum(lst))   # 23

排序

python 复制代码
# sorted() - 返回新列表,不修改原对象
numbers = [3, 1, 4, 1, 5, 9]
sorted_nums = sorted(numbers)
print(sorted_nums)       # [1, 1, 3, 4, 5, 9]
print(numbers)           # [3, 1, 4, 1, 5, 9](未改变)

# 自定义排序
students = [
    {"name": "张三", "score": 85},
    {"name": "李四", "score": 92},
    {"name": "王五", "score": 78}
]

# 按分数排序
sorted_students = sorted(students, key=lambda s: s["score"])
for s in sorted_students:
    print(f"{s['name']}: {s['score']}")

# 降序
sorted_desc = sorted(students, key=lambda s: s["score"], reverse=True)

枚举和压缩

python 复制代码
# enumerate - 获取索引和值
fruits = ["苹果", "香蕉", "橙子"]
for index, fruit in enumerate(fruits, start=1):
    print(f"{index}. {fruit}")

# zip - 并行迭代
names = ["张三", "李四", "王五"]
ages = [20, 25, 30]
for name, age in zip(names, ages):
    print(f"{name}: {age}岁")

映射和过滤

python 复制代码
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

# map - 映射
squares = list(map(lambda x: x**2, numbers))
print(squares)  # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

# filter - 过滤
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens)  # [2, 4, 6, 8, 10]

# 推荐使用列表推导式替代
squares = [x**2 for x in numbers]
evens = [x for x in numbers if x % 2 == 0]

any 和 all

python 复制代码
# any - 至少一个为 True
print(any([False, False, True]))   # True
print(any([False, False, False]))  # False

# all - 全部为 True
print(all([True, True, True]))     # True
print(all([True, False, True]))    # False

# 实际应用
numbers = [1, 2, 3, 4, 5]
print(all(n > 0 for n in numbers))      # True
print(any(n % 2 == 0 for n in numbers)) # True

综合实战

实战1: 通讯录管理系统

python 复制代码
class ContactBook:
    def __init__(self):
        self.contacts = {}

    def add_contact(self):
        """添加联系人"""
        name = input("姓名: ")
        if name in self.contacts:
            print("联系人已存在!")
            return

        phone = input("电话: ")
        email = input("邮箱: ")
        address = input("地址: ")

        self.contacts[name] = {
            "phone": phone,
            "email": email,
            "address": address
        }
        print(f"联系人 {name} 添加成功!")

    def search_contact(self):
        """搜索联系人"""
        keyword = input("请输入搜索关键词: ")
        results = {name: info for name, info in self.contacts.items()
                   if keyword in name}

        if not results:
            print("未找到匹配的联系人")
        else:
            print(f"\n找到 {len(results)} 个结果:")
            for name, info in results.items():
                print(f"\n姓名: {name}")
                print(f"电话: {info['phone']}")
                print(f"邮箱: {info['email']}")
                print(f"地址: {info['address']}")

    def delete_contact(self):
        """删除联系人"""
        name = input("请输入要删除的联系人姓名: ")
        if name in self.contacts:
            del self.contacts[name]
            print(f"联系人 {name} 已删除")
        else:
            print("联系人不存在")

    def show_all_contacts(self):
        """显示所有联系人"""
        if not self.contacts:
            print("通讯录为空")
            return

        print("\n" + "=" * 50)
        print(f"{'姓名':<10}{'电话':<15}{'邮箱':<20}{'地址'}")
        print("=" * 50)

        for name, info in sorted(self.contacts.items()):
            print(f"{name:<10}{info['phone']:<15}{info['email']:<20}{info['address']}")

        print("=" * 50)
        print(f"共 {len(self.contacts)} 个联系人")

    def update_contact(self):
        """更新联系人"""
        name = input("请输入要更新的联系人姓名: ")
        if name not in self.contacts:
            print("联系人不存在")
            return

        print("直接回车保留原值")
        phone = input(f"电话 ({self.contacts[name]['phone']}): ")
        email = input(f"邮箱 ({self.contacts[name]['email']}): ")
        address = input(f"地址 ({self.contacts[name]['address']}): ")

        if phone:
            self.contacts[name]["phone"] = phone
        if email:
            self.contacts[name]["email"] = email
        if address:
            self.contacts[name]["address"] = address

        print("联系人信息已更新")

def main():
    book = ContactBook()

    while True:
        print("\n=== 通讯录管理系统 ===")
        print("1. 添加联系人")
        print("2. 搜索联系人")
        print("3. 删除联系人")
        print("4. 查看所有联系人")
        print("5. 更新联系人")
        print("6. 退出")

        choice = input("请选择操作: ")

        match choice:
            case "1":
                book.add_contact()
            case "2":
                book.search_contact()
            case "3":
                book.delete_contact()
            case "4":
                book.show_all_contacts()
            case "5":
                book.update_contact()
            case "6":
                print("感谢使用,再见!")
                break
            case _:
                print("无效选择")

if __name__ == "__main__":
    main()

实战2: 单词频率统计器

python 复制代码
import re
from collections import Counter

def analyze_text(text):
    """分析文本"""
    # 提取单词(只保留字母和数字)
    words = re.findall(r'\b[a-zA-Z0-9]+\b', text.lower())

    if not words:
        print("未找到有效单词")
        return

    # 统计词频
    word_counts = Counter(words)

    # 基本信息
    total_words = len(words)
    unique_words = len(word_counts)

    print("=" * 50)
    print("       文本分析报告")
    print("=" * 50)
    print(f"总单词数: {total_words}")
    print(f"不同单词数: {unique_words}")
    print(f"平均词长: {sum(len(w) for w in words) / total_words:.2f}")

    # Top 10 高频词
    print("\nTop 10 高频词:")
    print(f"{'排名':<6}{'单词':<15}{'次数':<8}{'频率'}")
    print("-" * 50)

    for rank, (word, count) in enumerate(word_counts.most_common(10), 1):
        frequency = count / total_words * 100
        print(f"{rank:<6}{word:<15}{count:<8}{frequency:.2f}%")

    # 词长分布
    length_dist = Counter(len(word) for word in words)
    print("\n词长分布:")
    for length in sorted(length_dist.keys()):
        count = length_dist[length]
        percentage = count / total_words * 100
        bar = "█" * int(percentage / 2)
        print(f"{length:2d} 字母: {count:4d} ({percentage:5.2f}%) {bar}")

# 测试
sample_text = """
Python is a great programming language. Python is easy to learn.
Many developers love Python because Python is powerful and versatile.
Programming in Python is fun and productive.
"""

analyze_text(sample_text)

# 交互式
print("\n" + "=" * 50)
user_text = input("请输入要分析的文本: ")
analyze_text(user_text)

实战3: 待办事项管理器

python 复制代码
import json
from datetime import datetime

class TodoManager:
    def __init__(self, filename="todos.json"):
        self.filename = filename
        self.todos = self.load_todos()

    def load_todos(self):
        """加载待办事项"""
        try:
            with open(self.filename, "r", encoding="utf-8") as f:
                return json.load(f)
        except (FileNotFoundError, json.JSONDecodeError):
            return []

    def save_todos(self):
        """保存待办事项"""
        with open(self.filename, "w", encoding="utf-8") as f:
            json.dump(self.todos, f, ensure_ascii=False, indent=2)

    def add_todo(self):
        """添加待办事项"""
        title = input("任务标题: ")
        priority = input("优先级 (高/中/低,默认中): ") or "中"
        due_date = input("截止日期 (YYYY-MM-DD,可选): ")

        todo = {
            "id": len(self.todos) + 1,
            "title": title,
            "priority": priority,
            "due_date": due_date if due_date else None,
            "completed": False,
            "created_at": datetime.now().strftime("%Y-%m-%d %H:%M:%S")
        }

        self.todos.append(todo)
        self.save_todos()
        print(f"任务 '{title}' 添加成功!")

    def show_todos(self, show_completed=False):
        """显示待办事项"""
        if not self.todos:
            print("暂无待办事项")
            return

        # 过滤
        filtered = [t for t in self.todos if show_completed or not t["completed"]]

        if not filtered:
            print("没有符合条件的任务")
            return

        # 排序:未完成优先,然后按优先级
        priority_order = {"高": 0, "中": 1, "低": 2}
        filtered.sort(key=lambda t: (t["completed"], priority_order.get(t["priority"], 1)))

        print("\n" + "=" * 70)
        print(f"{'ID':<4}{'状态':<6}{'优先级':<6}{'标题':<20}{'截止日期':<12}{'创建时间'}")
        print("=" * 70)

        for todo in filtered:
            status = "✓" if todo["completed"] else "○"
            due = todo["due_date"] or "-"
            print(f"{todo['id']:<4}{status:<6}{todo['priority']:<6}"
                  f"{todo['title']:<20}{due:<12}{todo['created_at']}")

        print("=" * 70)
        completed = sum(1 for t in self.todos if t["completed"])
        print(f"总计: {len(self.todos)} | 已完成: {completed} | 未完成: {len(self.todos) - completed}")

    def complete_todo(self):
        """完成任务"""
        try:
            todo_id = int(input("请输入任务ID: "))
            todo = next((t for t in self.todos if t["id"] == todo_id), None)

            if todo:
                todo["completed"] = True
                todo["completed_at"] = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
                self.save_todos()
                print(f"任务 '{todo['title']}' 已完成!")
            else:
                print("任务不存在")
        except ValueError:
            print("请输入有效的ID")

    def delete_todo(self):
        """删除任务"""
        try:
            todo_id = int(input("请输入要删除的任务ID: "))
            todo = next((t for t in self.todos if t["id"] == todo_id), None)

            if todo:
                self.todos.remove(todo)
                self.save_todos()
                print(f"任务 '{todo['title']}' 已删除")
            else:
                print("任务不存在")
        except ValueError:
            print("请输入有效的ID")

    def search_todos(self):
        """搜索任务"""
        keyword = input("请输入搜索关键词: ")
        results = [t for t in self.todos if keyword.lower() in t["title"].lower()]

        if not results:
            print("未找到匹配的任务")
        else:
            print(f"\n找到 {len(results)} 个结果:")
            for todo in results:
                status = "✓" if todo["completed"] else "○"
                print(f"[{status}] ID:{todo['id']} {todo['title']}")

def main():
    manager = TodoManager()

    while True:
        print("\n=== 待办事项管理器 ===")
        print("1. 添加任务")
        print("2. 查看任务")
        print("3. 查看所有任务(包括已完成)")
        print("4. 完成任务")
        print("5. 删除任务")
        print("6. 搜索任务")
        print("7. 退出")

        choice = input("请选择操作: ")

        match choice:
            case "1":
                manager.add_todo()
            case "2":
                manager.show_todos()
            case "3":
                manager.show_todos(show_completed=True)
            case "4":
                manager.complete_todo()
            case "5":
                manager.delete_todo()
            case "6":
                manager.search_todos()
            case "7":
                print("感谢使用,再见!")
                break
            case _:
                print("无效选择")

if __name__ == "__main__":
    main()

实战4: 简易数据库查询系统

python 复制代码
class SimpleDB:
    def __init__(self):
        self.tables = {}

    def create_table(self, table_name, columns):
        """创建表"""
        if table_name in self.tables:
            print(f"表 '{table_name}' 已存在")
            return

        self.tables[table_name] = {
            "columns": columns,
            "data": []
        }
        print(f"表 '{table_name}' 创建成功")

    def insert(self, table_name, record):
        """插入记录"""
        if table_name not in self.tables:
            print(f"表 '{table_name}' 不存在")
            return

        table = self.tables[table_name]

        # 验证字段
        for key in record.keys():
            if key not in table["columns"]:
                print(f"未知字段: {key}")
                return

        # 添加 ID
        record["id"] = len(table["data"]) + 1
        table["data"].append(record)
        print(f"记录插入成功,ID: {record['id']}")

    def select(self, table_name, conditions=None, order_by=None):
        """查询记录"""
        if table_name not in self.tables:
            print(f"表 '{table_name}' 不存在")
            return []

        table = self.tables[table_name]
        results = table["data"].copy()

        # 应用条件
        if conditions:
            filtered = []
            for record in results:
                match = True
                for key, value in conditions.items():
                    if record.get(key) != value:
                        match = False
                        break
                if match:
                    filtered.append(record)
            results = filtered

        # 排序
        if order_by:
            results.sort(key=lambda x: x.get(order_by, ""))

        return results

    def update(self, table_name, conditions, updates):
        """更新记录"""
        if table_name not in self.tables:
            print(f"表 '{table_name}' 不存在")
            return 0

        table = self.tables[table_name]
        count = 0

        for record in table["data"]:
            match = all(record.get(k) == v for k, v in conditions.items())
            if match:
                record.update(updates)
                count += 1

        print(f"更新了 {count} 条记录")
        return count

    def delete(self, table_name, conditions):
        """删除记录"""
        if table_name not in self.tables:
            print(f"表 '{table_name}' 不存在")
            return 0

        table = self.tables[table_name]
        original_count = len(table["data"])

        table["data"] = [
            record for record in table["data"]
            if not all(record.get(k) == v for k, v in conditions.items())
        ]

        deleted = original_count - len(table["data"])
        print(f"删除了 {deleted} 条记录")
        return deleted

    def show_table(self, table_name):
        """显示表结构和数据"""
        if table_name not in self.tables:
            print(f"表 '{table_name}' 不存在")
            return

        table = self.tables[table_name]

        print(f"\n表: {table_name}")
        print(f"字段: {', '.join(table['columns'])}")
        print(f"记录数: {len(table['data'])}")

        if table["data"]:
            print("\n数据:")
            headers = table["columns"]

            # 打印表头
            header_str = " | ".join(f"{h:<15}" for h in headers)
            print(header_str)
            print("-" * len(header_str))

            # 打印数据
            for record in table["data"]:
                row_str = " | ".join(f"{str(record.get(h, '')):<15}" for h in headers)
                print(row_str)

def demo():
    """演示"""
    db = SimpleDB()

    # 创建表
    db.create_table("students", ["name", "age", "major", "score"])

    # 插入数据
    db.insert("students", {"name": "张三", "age": 20, "major": "CS", "score": 90})
    db.insert("students", {"name": "李四", "age": 22, "major": "Math", "score": 85})
    db.insert("students", {"name": "王五", "age": 21, "major": "CS", "score": 92})
    db.insert("students", {"name": "赵六", "age": 23, "major": "Physics", "score": 88})

    # 显示表
    db.show_table("students")

    # 查询
    print("\n=== 查询 CS 专业的学生 ===")
    cs_students = db.select("students", {"major": "CS"})
    for student in cs_students:
        print(f"  {student['name']}: {student['score']}分")

    # 更新
    print("\n=== 更新张三的成绩 ===")
    db.update("students", {"name": "张三"}, {"score": 95})

    # 删除
    print("\n=== 删除赵六的记录 ===")
    db.delete("students", {"name": "赵六"})

    # 再次显示
    db.show_table("students")

if __name__ == "__main__":
    demo()

常见错误与注意事项

1. 可变对象的引用问题

python 复制代码
# ❌ 陷阱:列表引用
list1 = [1, 2, 3]
list2 = list1
list2.append(4)
print(list1)  # [1, 2, 3, 4](被意外修改)

# ✅ 正确:创建副本
list1 = [1, 2, 3]
list2 = list1.copy()  # 或 list2 = list1[:]
list2.append(4)
print(list1)  # [1, 2, 3]

# 对于嵌套结构,使用深拷贝
import copy
nested = [[1, 2], [3, 4]]
nested_copy = copy.deepcopy(nested)

2. 字典键的要求

python 复制代码
# ✅ 可哈希的类型可以作为键
d = {
    "string": 1,
    42: 2,
    (1, 2): 3,
    frozenset([1, 2]): 4
}

# ❌ 不可哈希的类型不能作为键
# d = {[1, 2]: 5}  # TypeError
# d = {{1, 2}: 6}  # TypeError

3. 遍历时修改容器

python 复制代码
# ❌ 危险:遍历时删除
numbers = [1, 2, 3, 4, 5]
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)  # 可能跳过元素

# ✅ 正确:创建新列表
numbers = [num for num in numbers if num % 2 != 0]

# ✅ 或者反向遍历
for num in reversed(numbers):
    if num % 2 == 0:
        numbers.remove(num)

4. 集合的空集创建

python 复制代码
# ❌ 错误:{} 是空字典
empty = {}
print(type(empty))  # <class 'dict'>

# ✅ 正确:使用 set()
empty_set = set()
print(type(empty_set))  # <class 'set'>

5. 字符串的不可变性

python 复制代码
# ❌ 不能直接修改字符串
# s = "hello"
# s[0] = "H"  # TypeError

# ✅ 创建新字符串
s = "hello"
s = "H" + s[1:]
print(s)  # Hello

# 或使用 replace
s = "hello"
s = s.replace("h", "H")

小结

容器类型 可变性 有序性 重复元素 典型用途
list 存储有序集合
tuple 固定数据、字典键
dict ✅* 键唯一 键值对映射
set 去重、集合运算
str 文本处理

*Python 3.7+ 字典保持插入顺序

核心要点

  • 列表最灵活,适合大多数场景
  • 元组不可变,适合固定数据
  • 字典用于键值对映射
  • 集合用于去重和集合运算
  • 字符串是不可变的字符序列
  • 注意可变对象的引用问题
  • 选择合适的容器能提升性能和代码可读性

掌握容器数据类型是 Python 编程的核心技能!

相关推荐
笨鸟先飞,勤能补拙2 小时前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能3 小时前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂3 小时前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study4 小时前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境4 小时前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境4 小时前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1235 小时前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102165 小时前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb006 小时前
一个项目带你入门AI应用开发01
python
0566466 小时前
Python康复训练——常用标准库
开发语言·python·学习