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 编程的核心技能!

相关推荐
云霄IT4 小时前
安卓开发之java转dex再转smali
android·java·python
果汁华4 小时前
Typer:基于类型提示的现代Python CLI框架
开发语言·网络·python
Claw开发者4 小时前
第1课:用20行Python造出你的第一个AI Agent
python
7年前端辞职转AI4 小时前
Python 流程控制语句
python·编程语言
7年前端辞职转AI4 小时前
Python 运算符
python·编程语言
zhangzeyuaaa4 小时前
Python 异常机制深度剖析
开发语言·python
Ulyanov5 小时前
打造现代化雷达电子对抗仿真界面 第一篇:tkinter/ttk 现代化高级技巧与复杂布局系统设计
python·信息可视化·系统仿真·雷达电子对抗
wgzrmlrm745 小时前
SQL实现按用户偏好进行分组汇总_自定义聚合规则
jvm·数据库·python
7年前端辞职转AI5 小时前
Python 变量
python·编程语言