数据存哪呢?

你有没有过这样的经历:

  • 需要存储100个学生成绩,总不能声明100个变量吧
  • 需要存储商品信息(名称、价格、库存),用什么存
  • 需要频繁添加、删除数据,用什么结构最合适

别再假装你会用100个变量解决问题了,用列表和字典吧!

列表和字典是Python最重要的两个数据结构,理解了它们,你就掌握了存储数据的艺术。

列表(list):有序的数据集合

创建列表

# 空列表
empty_list = []

# 包含多个元素的列表
numbers = [1, 2, 3, 4, 5]
names = ["小明", "小红", "小刚"]
mixed = [1, "Hello", True, 3.14]  # 什么类型都能放

访问元素

names = ["小明", "小红", "小刚", "小李"]

# 索引访问(从0开始)
print(names[0])   # 输出:小明
print(names[1])   # 输出:小红
print(names[-1])  # 输出:小李(最后一个)
print(names[-2])  # 输出:小刚(倒数第二个)

# 切片
print(names[0:2])    # 输出:['小明', '小红']
print(names[1:3])    # 输出:['小红', '小刚']
print(names[:2])     # 输出:['小明', '小红']
print(names[1:])     # 输出:['小红', '小刚', '小李']

添加元素

numbers = [1, 2, 3]

# append():在末尾添加一个元素
numbers.append(4)
print(numbers)  # 输出:[1, 2, 3, 4]

# insert():在指定位置插入元素
numbers.insert(1, 100)
print(numbers)  # 输出:[1, 100, 2, 3, 4]

# extend():在末尾添加多个元素
numbers.extend([5, 6, 7])
print(numbers)  # 输出:[1, 100, 2, 3, 4, 5, 6, 7]

# 列表拼接(创建新列表)
new_list = numbers + [8, 9, 10]
print(new_list)  # 输出:[1, 100, 2, 3, 4, 5, 6, 7, 8, 9, 10]

删除元素

numbers = [1, 2, 3, 4, 5]

# del:根据索引删除
del numbers[1]
print(numbers)  # 输出:[1, 3, 4, 5]

# remove():根据值删除(只删除第一个)
numbers.remove(3)
print(numbers)  # 输出:[1, 4, 5]

# pop():删除并返回指定位置的元素
element = numbers.pop(1)
print(element)  # 输出:4
print(numbers)  # 输出:[1, 5]

# pop():不指定索引,删除最后一个
element = numbers.pop()
print(element)  # 输出:5
print(numbers)  # 输出:[1]

修改元素

numbers = [1, 2, 3, 4, 5]

# 根据索引修改
numbers[0] = 100
print(numbers)  # 输出:[100, 2, 3, 4, 5]

# 修改多个元素
numbers[1:3] = [200, 300]
print(numbers)  # 输出:[100, 200, 300, 4, 5]

其他常用操作

numbers = [3, 1, 4, 1, 5, 9, 2, 6]

# len():获取长度
print(len(numbers))  # 输出:8

# sort():排序(升序)
numbers.sort()
print(numbers)  # 输出:[1, 1, 2, 3, 4, 5, 6, 9]

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

# reverse():反转
numbers.reverse()
print(numbers)  # 输出:[1, 1, 2, 3, 4, 5, 6, 9]

# count():统计元素出现次数
print(numbers.count(1))  # 输出:2

# index():查找元素的索引
print(numbers.index(5))  # 输出:4

# in:判断元素是否存在
print(5 in numbers)  # 输出:True
print(10 in numbers)  # 输出:False

列表推导式(优雅的创建列表)

# 传统方式
squares = []
for i in range(1, 6):
    squares.append(i * i)
print(squares)  # 输出:[1, 4, 9, 16, 25]

# 列表推导式
squares = [i * i for i in range(1, 6)]
print(squares)  # 输出:[1, 4, 9, 16, 25]

# 带条件的列表推导式
even_numbers = [i for i in range(1, 11) if i % 2 == 0]
print(even_numbers)  # 输出:[2, 4, 6, 8, 10]

字典(dict):键值对的数据集合

创建字典

# 空字典
empty_dict = {}

# 包含多个键值对
person = {
    "name": "小明",
    "age": 25,
    "job": "程序员"
}

# 用dict()函数创建
person = dict(name="小明", age=25, job="程序员")

访问和修改

person = {
    "name": "小明",
    "age": 25,
    "job": "程序员"
}

# 访问值
print(person["name"])  # 输出:小明
print(person["age"])   # 输出:25

# get()方法(推荐,不会报错)
print(person.get("name"))      # 输出:小明
print(person.get("height"))    # 输出:None(键不存在时返回None)
print(person.get("height", 1.75))  # 输出:1.75(键不存在时返回默认值)

# 修改值
person["age"] = 26
print(person)  # 输出:{'name': '小明', 'age': 26, 'job': '程序员'}

# 添加键值对
person["height"] = 1.75
print(person)  # 输出:{'name': '小明', 'age': 26, 'job': '程序员', 'height': 1.75}

删除键值对

person = {
    "name": "小明",
    "age": 25,
    "job": "程序员"
}

# del:删除键值对
del person["job"]
print(person)  # 输出:{'name': '小明', 'age': 25}

# pop():删除并返回值
age = person.pop("age")
print(age)    # 输出:25
print(person)  # 输出:{'name': '小明'}

常用操作

person = {
    "name": "小明",
    "age": 25,
    "job": "程序员"
}

# keys():获取所有键
print(person.keys())  # 输出:dict_keys(['name', 'age', 'job'])

# values():获取所有值
print(person.values())  # 输出:dict_values(['小明', 25, '程序员'])

# items():获取所有键值对
print(person.items())  # 输出:dict_items([('name', '小明'), ('age', 25), ('job', '程序员')])

# 遍历字典
for key in person:
    print(key, person[key])

# 推荐:同时遍历键和值
for key, value in person.items():
    print(f"{key}: {value}")

# len():获取键值对数量
print(len(person))  # 输出:3

# in:判断键是否存在
print("name" in person)  # 输出:True
print("height" in person)  # 输出:False

字典推导式

# 传统方式
squares = {}
for i in range(1, 6):
    squares[i] = i * i
print(squares)  # 输出:{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}

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

列表 vs 字典:什么时候用哪个?

场景 推荐使用 原因
存储有序数据 列表 有索引,按顺序访问
存储无序但有关联的数据 字典 用键访问,语义清晰
需要频繁添加删除 列表 操作简单
需要按键查找 字典 查找速度快
数据有重复 列表 允许重复
数据唯一 字典 键唯一

实战小项目1:学生成绩管理系统

# 存储学生成绩
students = [
    {"name": "小明", "score": 85},
    {"name": "小红", "score": 92},
    {"name": "小刚", "score": 78},
    {"name": "小李", "score": 88}
]

# 计算平均分
total_score = sum(student["score"] for student in students)
average_score = total_score / len(students)
print(f"平均分:{average_score:.2f}")

# 找出最高分和最低分
max_score_student = max(students, key=lambda x: x["score"])
min_score_student = min(students, key=lambda x: x["score"])
print(f"最高分:{max_score_student['name']} - {max_score_student['score']}")
print(f"最低分:{min_score_student['name']} - {min_score_student['score']}")

# 排序(按分数降序)
students.sort(key=lambda x: x["score"], reverse=True)
print("\n排名:")
for i, student in enumerate(students, 1):
    print(f"第{i}名:{student['name']} - {student['score']}")

实战小项目2:商品库存管理

# 商品库存
inventory = {
    "苹果": 100,
    "香蕉": 80,
    "橙子": 60,
    "草莓": 40
}

# 查询库存
def check_inventory(product):
    if product in inventory:
        print(f"{product}还有{inventory[product]}个")
    else:
        print(f"没有{product}")

check_inventory("苹果")  # 输出:苹果还有100个
check_inventory("葡萄")  # 输出:没有葡萄

# 出库
def sell_product(product, quantity):
    if product not in inventory:
        print(f"没有{product}!")
        return

    if inventory[product] >= quantity:
        inventory[product] -= quantity
        print(f"卖出{quantity}{product},剩余{inventory[product]}个")
    else:
        print(f"{product}库存不足!只有{inventory[product]}个")

sell_product("苹果", 20)  # 输出:卖出20个苹果,剩余80个
sell_product("草莓", 50)  # 输出:草莓库存不足!只有40个

# 入库
def add_product(product, quantity):
    if product in inventory:
        inventory[product] += quantity
    else:
        inventory[product] = quantity
    print(f"{product}入库{quantity}个,当前库存:{inventory[product]}")

add_product("苹果", 30)  # 输出:苹果入库30个,当前库存:110
add_product("葡萄", 50)  # 输出:葡萄入库50个,当前库存:50

# 查看所有库存
def show_all_inventory():
    print("\n当前库存:")
    for product, quantity in inventory.items():
        print(f"{product}: {quantity}")

show_all_inventory()

实战小项目3:词频统计

def count_words(text):
    """统计词频"""
    # 去除标点符号,转小写
    text = text.replace(".", "").replace(",", "").replace("!", "").replace("?", "")
    text = text.lower()

    # 分割单词
    words = text.split()

    # 统计词频
    word_count = {}
    for word in words:
        if word in word_count:
            word_count[word] += 1
        else:
            word_count[word] = 1

    return word_count

text = """
Python is a great programming language. Python is easy to learn.
Python is powerful. I love Python!
"""

word_count = count_words(text)

# 按词频排序
sorted_word_count = sorted(word_count.items(), key=lambda x: x[1], reverse=True)

print("词频统计:")
for word, count in sorted_word_count:
    print(f"{word}: {count}")

常见坑及解决方案

坑1:修改循环中的列表

numbers = [1, 2, 3, 4, 5]

# 错误做法
for num in numbers:
    if num % 2 == 0:
        numbers.remove(num)  # 跳过了后面的元素
print(numbers)  # 输出:[1, 3, 5](跳过了4)

# 正确做法1:用切片复制
for num in numbers[:]:
    if num % 2 == 0:
        numbers.remove(num)

# 正确做法2:用列表推导式
numbers = [num for num in numbers if num % 2 != 0]

坑2:列表作为默认参数

def add_item(item, items=[]):  # 危险!
    items.append(item)
    return items

print(add_item("apple"))  # 输出:['apple']
print(add_item("banana"))  # 输出:['apple', 'banana'](不是你想要的!)

# 正确做法
def add_item(item, items=None):
    if items is None:
        items = []
    items.append(item)
    return items

print(add_item("apple"))  # 输出:['apple']
print(add_item("banana"))  # 输出:['banana']

本章小结

  • 列表:有序数据集合,用索引访问
  • 字典:键值对数据集合,用键访问
  • 列表操作:append()、insert()、extend()、remove()、pop()、sort()、列表推导式
  • 字典操作:访问、添加、删除、keys()、values()、items()、字典推导式
  • 实战项目:学生成绩管理、商品库存管理、词频统计

列表和字典让你能存储和管理各种数据。下一章我们学习文件操作,读写Excel、Word、PDF!

继续学下去,马上就能做实用项目了!