08-列表和字典-存储和管理数据
数据存哪呢?
你有没有过这样的经历:
- 需要存储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!
继续学下去,马上就能做实用项目了!