列表(List)是Python中最常用的数据结构之一,用于存储一组有序的数据。列表具有以下重要特性:
[]
表示,元素之间用逗号分隔。索引从0开始计数。
# 定义列表
nums = [1, 2, 3, 4, 5]
words = ["apple", "banana", "cherry"]
mixed = [1, "hello", True, 3.14, [1, 2, 3]]
# 访问元素(索引从0开始)
print(nums[0]) # 1
print(words[2]) # cherry
print(mixed[-1]) # [1, 2, 3] (最后一个元素)
# 切片访问
print(nums[1:4]) # [2, 3, 4]
print(nums[::2]) # [1, 3, 5] (步长为2)
Python列表提供了丰富的内置方法来操作数据:
append(x)
:在列表末尾添加单个元素insert(i, x)
:在索引i处插入元素xextend(iterable)
:添加可迭代对象中的所有元素remove(x)
:移除首次出现的元素xpop(i)
:移除并返回索引i处的元素len()
:获取列表长度
# 列表操作示例
fruits = ["apple", "banana"]
print(f"原始列表: {fruits}")
# 添加元素
fruits.append("cherry")
fruits.insert(1, "orange")
fruits.extend(["grape", "mango"])
print(f"添加后: {fruits}")
# 删除元素
removed = fruits.pop() # 删除并返回最后一个元素
fruits.remove("orange") # 删除指定元素
print(f"删除后: {fruits}")
print(f"被删除的元素: {removed}")
# 获取信息
print(f"列表长度: {len(fruits)}")
print(f"是否包含'banana': {'banana' in fruits}")
列表切片和遍历是处理数据的重要技巧:
list[start:end:step]
,其中start是起始索引,end是结束索引(不包含),step是步长。
# 切片操作详解
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 基本切片
print(numbers[2:5]) # [2, 3, 4] (索引2到4)
print(numbers[:3]) # [0, 1, 2] (从开始到索引2)
print(numbers[7:]) # [7, 8, 9] (从索引7到结束)
# 步长切片
print(numbers[::2]) # [0, 2, 4, 6, 8] (偶数索引)
print(numbers[1::2]) # [1, 3, 5, 7, 9] (奇数索引)
print(numbers[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (反转)
# 负索引切片
print(numbers[-3:]) # [7, 8, 9] (最后3个元素)
print(numbers[:-2]) # [0, 1, 2, 3, 4, 5, 6, 7] (除了最后2个)
# 遍历方式
print("方式1:直接遍历元素")
for num in numbers:
print(num, end=" ")
print()
print("方式2:遍历索引和元素")
for i, num in enumerate(numbers):
print(f"索引{i}: {num}")
print("方式3:遍历索引")
for i in range(len(numbers)):
print(f"位置{i}: {numbers[i]}")
列表推导式是Python的优雅特性,可以用简洁的语法快速生成列表:
[expression for item in iterable if condition]
expression
:对每个元素进行的操作item
:迭代变量iterable
:可迭代对象if condition
:可选的条件筛选
# 列表推导式示例
# 基础推导式:生成1-10的平方
squares = [x**2 for x in range(1, 11)]
print(f"平方数: {squares}")
# 条件推导式:筛选偶数
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = [x for x in numbers if x % 2 == 0]
print(f"偶数: {evens}")
# 复杂推导式:字符串处理
words = ["hello", "world", "python", "programming"]
upper_words = [word.upper() for word in words if len(word) > 5]
print(f"长单词转大写: {upper_words}")
# 嵌套推导式:二维列表转一维
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(f"展平矩阵: {flattened}")
# 条件表达式推导式
result = [x if x > 0 else -x for x in [-1, 2, -3, 4, -5]]
print(f"绝对值: {result}")
# 字典推导式(扩展知识)
word_lengths = {word: len(word) for word in words}
print(f"单词长度字典: {word_lengths}")
列表可以嵌套,形成二维、三维甚至更高维的数据结构:
# 嵌套列表示例
# 二维列表(矩阵)
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print("矩阵:")
for row in matrix:
print(row)
print(f"元素[1][2]: {matrix[1][2]}") # 6
# 创建3x3单位矩阵
def create_identity_matrix(n):
return [[1 if i == j else 0 for j in range(n)] for i in range(n)]
identity = create_identity_matrix(3)
print("单位矩阵:")
for row in identity:
print(row)
# 三维列表(立方体)
cube = [
[[1, 2], [3, 4]],
[[5, 6], [7, 8]]
]
print(f"立方体[0][1][0]: {cube[0][1][0]}") # 3
# 不规则嵌套列表
irregular = [
[1, 2, 3],
[4, 5],
[6, 7, 8, 9],
[10]
]
print("不规则列表:")
for i, row in enumerate(irregular):
print(f"行{i}: {row} (长度: {len(row)})")
Python提供了许多内置函数来简化列表操作:
sum()
:计算数值列表的总和max()
、min()
:找出最大/最小值sorted()
:返回排序后的新列表reversed()
:返回反转的迭代器any()
、all()
:检查条件
# 内置函数示例
# 数值计算
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
print(f"原始列表: {numbers}")
print(f"总和: {sum(numbers)}")
print(f"最大值: {max(numbers)}")
print(f"最小值: {min(numbers)}")
print(f"平均值: {sum(numbers) / len(numbers):.2f}")
# 排序和反转
print(f"升序排序: {sorted(numbers)}")
print(f"降序排序: {sorted(numbers, reverse=True)}")
print(f"反转: {list(reversed(numbers))}")
# 条件检查
print(f"是否所有数都大于0: {all(x > 0 for x in numbers)}")
print(f"是否有数大于8: {any(x > 8 for x in numbers)}")
# 高级排序
students = [
{"name": "Alice", "age": 20, "grade": 85},
{"name": "Bob", "age": 19, "grade": 92},
{"name": "Charlie", "age": 21, "grade": 78}
]
# 按成绩排序
by_grade = sorted(students, key=lambda x: x["grade"], reverse=True)
print("按成绩排序:")
for student in by_grade:
print(f"{student['name']}: {student['grade']}")
# 按年龄排序
by_age = sorted(students, key=lambda x: x["age"])
print("按年龄排序:")
for student in by_age:
print(f"{student['name']}: {student['age']}岁")
理解列表的核心特性对于正确使用Python列表至关重要:
# 基础特性示例
lst = [1, "hello", True, [2, 3]]
print(f"原始列表: {lst}")
print(f"列表类型: {type(lst)}")
print(f"列表长度: {len(lst)}")
# 可变性演示
print("\n=== 可变性演示 ===")
original_id = id(lst)
lst[0] = 100
lst.append("new_item")
print(f"修改后: {lst}")
print(f"内存地址变化: {id(lst) == original_id}") # True
# 有序性演示
print("\n=== 有序性演示 ===")
print(f"第一个元素: {lst[0]}")
print(f"最后一个元素: {lst[-1]}")
print(f"切片[1:3]: {lst[1:3]}")
print(f"步长切片[::2]: {lst[::2]}")
# 元素多样性演示
print("\n=== 元素多样性演示 ===")
for i, item in enumerate(lst):
print(f"索引{i}: {item} (类型: {type(item)})")
列表的增删改操作是日常编程中最常用的功能:
list.append(x)
:在列表末尾添加单个元素list.extend(iterable)
:在列表末尾添加可迭代对象中的所有元素list.insert(i, x)
:在索引i处插入元素x,原元素后移list += iterable
:扩展列表(等同于extend)
# 增加元素示例
fruits = ["apple"]
print(f"初始列表: {fruits}")
# 添加单个元素
fruits.append("banana")
print(f"append后: {fruits}")
# 插入元素
fruits.insert(1, "orange")
print(f"insert后: {fruits}")
# 扩展列表
fruits.extend(["cherry", "date", "elderberry"])
print(f"extend后: {fruits}")
# 使用+=操作符
fruits += ["fig", "grape"]
print(f"+=操作后: {fruits}")
# 在指定位置插入多个元素
fruits[2:2] = ["kiwi", "lemon"]
print(f"切片插入后: {fruits}")
list.remove(x)
:移除列表中首次出现的元素xlist.pop(i)
:移除并返回索引i处的元素,默认移除最后一个del list[i]
:删除指定索引的元素(无返回值)list.clear()
:清空列表
# 删除元素示例
numbers = [1, 2, 3, 2, 4, 5, 2, 6]
print(f"原始列表: {numbers}")
# 删除指定值
numbers.remove(2) # 只删除第一个2
print(f"remove(2)后: {numbers}")
# 弹出元素
popped = numbers.pop() # 删除并返回最后一个元素
print(f"pop()后: {numbers}")
print(f"被弹出的元素: {popped}")
popped_index = numbers.pop(1) # 删除索引1的元素
print(f"pop(1)后: {numbers}")
print(f"被弹出的元素: {popped_index}")
# 删除指定索引
del numbers[0]
print(f"del numbers[0]后: {numbers}")
# 删除切片
del numbers[1:3]
print(f"del numbers[1:3]后: {numbers}")
# 清空列表
numbers.clear()
print(f"clear()后: {numbers}")
lst[i] = new_value
lst[start:end] = iterable
# 修改元素示例
lst = [1, 2, 3, 4, 5]
print(f"原始列表: {lst}")
# 修改单个元素
lst[2] = 30
print(f"修改索引2后: {lst}")
# 通过切片修改
lst[1:4] = [20, 30, 40]
print(f"切片修改[1:4]后: {lst}")
# 切片长度可不同
lst[1:3] = [200]
print(f"切片修改[1:3]后: {lst}")
# 条件修改
for i in range(len(lst)):
if lst[i] % 2 == 0:
lst[i] *= 10
print(f"偶数乘10后: {lst}")
# 列表推导式修改
lst = [x * 2 if x % 2 == 0 else x for x in lst]
print(f"推导式修改后: {lst}")
列表的查询和排序操作是数据处理中的核心功能:
list.index(x, start, end)
:返回元素x在列表中首次出现的索引list.count(x)
:统计元素x在列表中出现的次数element in list
:检查元素是否存在于列表中
# 查询操作示例
lst = [1, 2, 3, 2, 4, 2, 5]
print(f"原始列表: {lst}")
# 查找元素索引
print(f"元素2首次出现位置: {lst.index(2)}") # 1
print(f"从索引2开始查找2: {lst.index(2, 2)}") # 3
print(f"元素2出现次数: {lst.count(2)}") # 3
# 检查元素存在性
print(f"元素3是否存在: {3 in lst}") # True
print(f"元素6是否存在: {6 in lst}") # False
# 查找所有匹配元素的索引
def find_all_indices(lst, target):
"""查找所有匹配元素的索引"""
return [i for i, x in enumerate(lst) if x == target]
print(f"元素2的所有位置: {find_all_indices(lst, 2)}") # [1, 3, 5]
list.sort(key=None, reverse=False)
:对列表原地排序sorted(iterable, key=None, reverse=False)
:返回新的排序列表list.reverse()
:将列表元素原地反转reversed(iterable)
:返回反转的迭代器
# 排序与反转示例
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
print(f"原始列表: {numbers}")
# 基本排序
numbers.sort() # 原地排序
print(f"升序排序: {numbers}") # [1, 1, 2, 3, 4, 5, 6, 9]
numbers.sort(reverse=True) # 降序排序
print(f"降序排序: {numbers}") # [9, 6, 5, 4, 3, 2, 1, 1]
# 自定义排序
words = ["cat", "dog", "elephant", "ant", "zebra"]
words.sort(key=len) # 按长度排序
print(f"按长度排序: {words}") # ['ant', 'cat', 'dog', 'zebra', 'elephant']
words.sort(key=str.lower) # 忽略大小写排序
print(f"忽略大小写排序: {words}") # ['ant', 'cat', 'dog', 'elephant', 'zebra']
# 复杂对象排序
students = [
{"name": "Alice", "age": 20, "grade": 85},
{"name": "Bob", "age": 19, "grade": 92},
{"name": "Charlie", "age": 21, "grade": 78}
]
# 按成绩排序
by_grade = sorted(students, key=lambda x: x["grade"], reverse=True)
print("按成绩排序:")
for student in by_grade:
print(f" {student['name']}: {student['grade']}")
# 按年龄排序
by_age = sorted(students, key=lambda x: x["age"])
print("按年龄排序:")
for student in by_age:
print(f" {student['name']}: {student['age']}岁")
# 多条件排序
by_grade_age = sorted(students, key=lambda x: (x["grade"], x["age"]), reverse=True)
print("按成绩和年龄排序:")
for student in by_grade_age:
print(f" {student['name']}: 成绩{student['grade']}, 年龄{student['age']}")
# 反转操作
numbers.reverse()
print(f"反转后: {numbers}") # [1, 1, 2, 3, 4, 5, 6, 9]
# 使用reversed()函数
rev_iter = reversed(numbers)
rev_list = list(rev_iter)
print(f"reversed()结果: {rev_list}") # [9, 6, 5, 4, 3, 2, 1, 1]
列表切片是Python的强大特性,而拷贝操作需要注意深浅拷贝的区别:
lst[start:end:step]
:返回新列表,包含从start到end-1的元素
# 切片操作详解
lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(f"原始列表: {lst}")
# 基本切片
print(f"lst[2:6]: {lst[2:6]}") # [2, 3, 4, 5]
print(f"lst[:5]: {lst[:5]}") # [0, 1, 2, 3, 4]
print(f"lst[5:]: {lst[5:]}") # [5, 6, 7, 8, 9]
print(f"lst[-3:]: {lst[-3:]}") # [7, 8, 9] (最后3个元素)
# 步长切片
print(f"lst[::2]: {lst[::2]}") # [0, 2, 4, 6, 8] (偶数索引)
print(f"lst[1::2]: {lst[1::2]}") # [1, 3, 5, 7, 9] (奇数索引)
print(f"lst[::3]: {lst[::3]}") # [0, 3, 6, 9] (步长为3)
# 负步长(反向)
print(f"lst[::-1]: {lst[::-1]}") # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (反转)
print(f"lst[::-2]: {lst[::-2]}") # [9, 7, 5, 3, 1] (反向步长为2)
# 负索引切片
print(f"lst[-5:-2]: {lst[-5:-2]}") # [5, 6, 7]
print(f"lst[-2:-5:-1]: {lst[-2:-5:-1]}") # [8, 7, 6] (反向切片)
# 切片赋值
lst_copy = lst.copy()
lst_copy[2:5] = [20, 30, 40]
print(f"切片赋值后: {lst_copy}")
# 切片删除
lst_copy[1:4] = []
print(f"切片删除后: {lst_copy}")
lst2 = lst1
(共享同一对象)lst.copy()
或 lst[:]
(只复制第一层)copy.deepcopy(lst)
(递归复制所有层)
# 拷贝操作详解
import copy
# 原始列表(包含嵌套结构)
original = [1, [2, 3], {"a": 4, "b": 5}]
print(f"原始列表: {original}")
# 1. 引用赋值(不是拷贝)
reference = original
print(f"引用赋值后: {reference}")
print(f"内存地址相同: {id(original) == id(reference)}") # True
# 修改引用会影响原列表
reference[0] = 100
print(f"修改引用后原列表: {original}") # [100, [2, 3], {"a": 4, "b": 5}]
# 2. 浅拷贝
shallow = original.copy() # 等同于 original[:]
print(f"浅拷贝后: {shallow}")
print(f"内存地址不同: {id(original) != id(shallow)}") # True
# 修改浅拷贝的第一层元素不会影响原列表
shallow[0] = 200
print(f"修改浅拷贝第一层后原列表: {original}") # [100, [2, 3], {"a": 4, "b": 5}]
# 但修改嵌套对象会影响原列表(因为共享同一对象)
shallow[1][0] = 20
print(f"修改浅拷贝嵌套层后原列表: {original}") # [100, [20, 3], {"a": 4, "b": 5}]
# 3. 深拷贝
deep = copy.deepcopy(original)
print(f"深拷贝后: {deep}")
print(f"内存地址不同: {id(original) != id(deep)}") # True
# 修改深拷贝的任何层都不会影响原列表
deep[1][1] = 30
deep[2]["a"] = 40
print(f"修改深拷贝后原列表: {original}") # [100, [20, 3], {"a": 4, "b": 5}]
print(f"深拷贝: {deep}") # [100, [20, 30], {"a": 40, "b": 5}]
# 性能对比
import time
def test_copy_performance():
large_list = [[i] for i in range(10000)]
# 测试浅拷贝
start = time.time()
shallow_copy = large_list.copy()
shallow_time = time.time() - start
# 测试深拷贝
start = time.time()
deep_copy = copy.deepcopy(large_list)
deep_time = time.time() - start
print(f"浅拷贝时间: {shallow_time:.4f}秒")
print(f"深拷贝时间: {deep_time:.4f}秒")
print(f"深拷贝比浅拷贝慢 {deep_time/shallow_time:.1f}倍")
test_copy_performance()
列表推导式是Python的优雅特性,可以用简洁的语法快速生成列表:
[expression for item in iterable]
[expression for item in iterable if condition]
[expression for item1 in iterable1 for item2 in iterable2]
[expression1 if condition else expression2 for item in iterable]
# 列表推导式详解
# 1. 基础推导式
print("=== 基础推导式 ===")
squares = [x**2 for x in range(1, 11)]
print(f"1-10的平方: {squares}")
cubes = [x**3 for x in range(1, 6)]
print(f"1-5的立方: {cubes}")
# 2. 条件筛选推导式
print("\n=== 条件筛选推导式 ===")
numbers = list(range(1, 21))
evens = [x for x in numbers if x % 2 == 0]
odds = [x for x in numbers if x % 2 == 1]
print(f"偶数: {evens}")
print(f"奇数: {odds}")
# 筛选质数
def is_prime(n):
if n < 2:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True
primes = [x for x in range(2, 50) if is_prime(x)]
print(f"质数: {primes}")
# 3. 字符串处理推导式
print("\n=== 字符串处理推导式 ===")
words = ["hello", "world", "python", "programming", "computer"]
long_words = [word.upper() for word in words if len(word) > 5]
print(f"长单词转大写: {long_words}")
# 字符统计
sentence = "hello world python programming"
char_count = {char: sentence.count(char) for char in set(sentence) if char != ' '}
print(f"字符统计: {char_count}")
# 4. 嵌套推导式
print("\n=== 嵌套推导式 ===")
# 二维列表转一维
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(f"展平矩阵: {flattened}")
# 生成乘法表
multiplication_table = [[i*j for j in range(1, 6)] for i in range(1, 6)]
print("乘法表:")
for row in multiplication_table:
print(f" {row}")
# 5. 条件表达式推导式
print("\n=== 条件表达式推导式 ===")
# 绝对值
numbers_with_signs = [-1, 2, -3, 4, -5, 6, -7, 8]
abs_values = [x if x > 0 else -x for x in numbers_with_signs]
print(f"绝对值: {abs_values}")
# 奇偶分类
classified = ["偶数" if x % 2 == 0 else "奇数" for x in range(1, 11)]
print(f"奇偶分类: {classified}")
# 6. 字典推导式(扩展)
print("\n=== 字典推导式 ===")
word_lengths = {word: len(word) for word in words}
print(f"单词长度字典: {word_lengths}")
# 7. 集合推导式(扩展)
print("\n=== 集合推导式 ===")
unique_lengths = {len(word) for word in words}
print(f"单词长度集合: {unique_lengths}")
# 8. 性能对比
print("\n=== 性能对比 ===")
import time
def traditional_way(n):
result = []
for i in range(n):
if i % 2 == 0:
result.append(i**2)
return result
def comprehension_way(n):
return [i**2 for i in range(n) if i % 2 == 0]
n = 1000000
start = time.time()
traditional_way(n)
traditional_time = time.time() - start
start = time.time()
comprehension_way(n)
comprehension_time = time.time() - start
print(f"传统方式时间: {traditional_time:.4f}秒")
print(f"推导式时间: {comprehension_time:.4f}秒")
print(f"推导式比传统方式快 {traditional_time/comprehension_time:.1f}倍")
Python中不同数据结构之间可以相互转换,掌握这些转换方法很有用:
"".join(lst)
(要求列表元素均为字符串)list(s)
或 s.split(sep)
list(tuple)
list(set)
(会丢失顺序,因集合无序)list(dict.keys())
、list(dict.values())
、list(dict.items())
# 数据结构转换详解
# 1. 列表与字符串转换
print("=== 列表与字符串转换 ===")
# 列表转字符串
chars = ['H', 'e', 'l', 'l', 'o']
word = ''.join(chars)
print(f"字符列表: {chars}")
print(f"转字符串: {word}")
# 带分隔符的转换
fruits = ['apple', 'banana', 'cherry']
fruits_str = ', '.join(fruits)
print(f"水果列表: {fruits}")
print(f"转字符串: {fruits_str}")
# 字符串转列表
sentence = "Hello World Python Programming"
char_list = list(sentence)
word_list = sentence.split()
print(f"句子: {sentence}")
print(f"转字符列表: {char_list}")
print(f"转单词列表: {word_list}")
# 按特定分隔符分割
csv_line = "张三,25,北京,工程师"
csv_list = csv_line.split(',')
print(f"CSV行: {csv_line}")
print(f"分割后: {csv_list}")
# 2. 列表与元组转换
print("\n=== 列表与元组转换 ===")
numbers_list = [1, 2, 3, 4, 5]
numbers_tuple = tuple(numbers_list)
print(f"列表: {numbers_list}")
print(f"转元组: {numbers_tuple}")
# 元组转列表
coordinates = (10, 20, 30)
coordinates_list = list(coordinates)
print(f"坐标元组: {coordinates}")
print(f"转列表: {coordinates_list}")
# 3. 列表与集合转换
print("\n=== 列表与集合转换 ===")
duplicate_numbers = [1, 2, 2, 3, 3, 4, 5, 5]
unique_numbers = list(set(duplicate_numbers))
print(f"有重复的列表: {duplicate_numbers}")
print(f"去重后: {unique_numbers}")
# 注意:集合无序,转换后顺序可能改变
original_order = [3, 1, 4, 1, 5, 9, 2, 6]
set_conversion = list(set(original_order))
print(f"原始顺序: {original_order}")
print(f"集合转换后: {set_conversion}")
# 4. 列表与字典转换
print("\n=== 列表与字典转换 ===")
student_info = {"name": "张三", "age": 20, "grade": "A"}
keys_list = list(student_info.keys())
values_list = list(student_info.values())
items_list = list(student_info.items())
print(f"学生信息: {student_info}")
print(f"键列表: {keys_list}")
print(f"值列表: {values_list}")
print(f"键值对列表: {items_list}")
# 列表转字典(需要特定格式)
pairs = [("a", 1), ("b", 2), ("c", 3)]
dict_from_pairs = dict(pairs)
print(f"键值对列表: {pairs}")
print(f"转字典: {dict_from_pairs}")
# 5. 高级转换技巧
print("\n=== 高级转换技巧 ===")
# 嵌套结构转换
nested_data = [
["name", "age", "city"],
["张三", 25, "北京"],
["李四", 30, "上海"],
["王五", 28, "广州"]
]
# 转换为字典列表
headers = nested_data[0]
data_dicts = []
for row in nested_data[1:]:
data_dicts.append(dict(zip(headers, row)))
print("嵌套数据:")
for row in nested_data:
print(f" {row}")
print("转换为字典列表:")
for data_dict in data_dicts:
print(f" {data_dict}")
# 6. 实际应用示例
print("\n=== 实际应用示例 ===")
# CSV数据处理
csv_data = [
"姓名,年龄,职业,城市",
"张三,25,工程师,北京",
"李四,30,设计师,上海",
"王五,28,教师,广州"
]
def parse_csv(csv_lines):
"""解析CSV数据"""
if not csv_lines:
return []
headers = csv_lines[0].split(',')
data = []
for line in csv_lines[1:]:
values = line.split(',')
row_dict = dict(zip(headers, values))
data.append(row_dict)
return data
parsed_data = parse_csv(csv_data)
print("解析后的CSV数据:")
for item in parsed_data:
print(f" {item}")
# 7. 性能考虑
print("\n=== 性能考虑 ===")
import time
def test_conversion_performance():
large_list = list(range(100000))
# 测试列表转元组
start = time.time()
tuple_result = tuple(large_list)
tuple_time = time.time() - start
# 测试列表转集合
start = time.time()
set_result = set(large_list)
set_time = time.time() - start
print(f"列表转元组时间: {tuple_time:.4f}秒")
print(f"列表转集合时间: {set_time:.4f}秒")
test_conversion_performance()
这是一个典型的CS106A项目,展示如何使用列表管理学生数据:
# 学生成绩管理系统
class Student:
def __init__(self, name, student_id):
self.name = name
self.student_id = student_id
self.grades = []
def add_grade(self, grade):
if 0 <= grade <= 100:
self.grades.append(grade)
else:
print(f"无效成绩: {grade}")
def get_average(self):
if not self.grades:
return 0
return sum(self.grades) / len(self.grades)
def get_letter_grade(self):
avg = self.get_average()
if avg >= 90: return 'A'
elif avg >= 80: return 'B'
elif avg >= 70: return 'C'
elif avg >= 60: return 'D'
else: return 'F'
# 创建学生列表
students = [
Student("Alice", "001"),
Student("Bob", "002"),
Student("Charlie", "003")
]
# 添加成绩
students[0].add_grade(95)
students[0].add_grade(88)
students[1].add_grade(92)
students[1].add_grade(85)
students[2].add_grade(78)
students[2].add_grade(82)
# 分析成绩
print("=== 学生成绩报告 ===")
for student in students:
print(f"{student.name} (ID: {student.student_id}):")
print(f" 成绩: {student.grades}")
print(f" 平均分: {student.get_average():.1f}")
print(f" 等级: {student.get_letter_grade()}")
print()
# 班级统计
all_grades = [grade for student in students for grade in student.grades]
print(f"班级平均分: {sum(all_grades) / len(all_grades):.1f}")
print(f"最高分: {max(all_grades)}")
print(f"最低分: {min(all_grades)}")
使用嵌套列表表示图像像素,这是计算机图形学的基础:
# 图像像素处理示例
def create_image(width, height, color=(255, 255, 255)):
"""创建指定尺寸的图像"""
return [[color for _ in range(width)] for _ in range(height)]
def set_pixel(image, x, y, color):
"""设置指定位置的像素颜色"""
if 0 <= y < len(image) and 0 <= x < len(image[0]):
image[y][x] = color
def draw_rectangle(image, x1, y1, x2, y2, color):
"""绘制矩形"""
for y in range(y1, y2 + 1):
for x in range(x1, x2 + 1):
set_pixel(image, x, y, color)
def draw_circle(image, center_x, center_y, radius, color):
"""绘制圆形(使用中点圆算法)"""
x, y = radius, 0
err = 0
while x >= y:
set_pixel(image, center_x + x, center_y + y, color)
set_pixel(image, center_x + y, center_y + x, color)
set_pixel(image, center_x - y, center_y + x, color)
set_pixel(image, center_x - x, center_y + y, color)
set_pixel(image, center_x - x, center_y - y, color)
set_pixel(image, center_x - y, center_y - x, color)
set_pixel(image, center_x + y, center_y - x, color)
set_pixel(image, center_x + x, center_y - y, color)
if err <= 0:
y += 1
err += 2*y + 1
if err > 0:
x -= 1
err -= 2*x + 1
def save_image(image, filename):
"""保存图像到文件(简化版)"""
with open(filename, 'w') as f:
f.write(f"P3\n{len(image[0])} {len(image)}\n255\n")
for row in image:
for pixel in row:
f.write(f"{pixel[0]} {pixel[1]} {pixel[2]} ")
f.write("\n")
# 创建图像并绘制
img = create_image(100, 100, (255, 255, 255)) # 白色背景
draw_rectangle(img, 20, 20, 80, 80, (255, 0, 0)) # 红色矩形
draw_circle(img, 50, 50, 30, (0, 0, 255)) # 蓝色圆形
print("图像创建完成!")
print(f"图像尺寸: {len(img[0])} x {len(img)}")
print(f"中心像素颜色: {img[50][50]}")
使用列表管理游戏状态,这是游戏开发中的常见应用:
# 简单的井字棋游戏状态管理
class TicTacToe:
def __init__(self):
self.board = [[' ' for _ in range(3)] for _ in range(3)]
self.current_player = 'X'
self.game_over = False
def make_move(self, row, col):
"""在指定位置下棋"""
if self.game_over or row < 0 or row > 2 or col < 0 or col > 2:
return False
if self.board[row][col] != ' ':
return False
self.board[row][col] = self.current_player
if self.check_winner(row, col):
self.game_over = True
return True
if self.is_board_full():
self.game_over = True
return True
self.current_player = 'O' if self.current_player == 'X' else 'X'
return True
def check_winner(self, row, col):
"""检查是否有获胜者"""
player = self.board[row][col]
# 检查行
if all(self.board[row][c] == player for c in range(3)):
return True
# 检查列
if all(self.board[r][col] == player for r in range(3)):
return True
# 检查对角线
if row == col and all(self.board[i][i] == player for i in range(3)):
return True
if row + col == 2 and all(self.board[i][2-i] == player for i in range(3)):
return True
return False
def is_board_full(self):
"""检查棋盘是否已满"""
return all(self.board[r][c] != ' ' for r in range(3) for c in range(3))
def display_board(self):
"""显示棋盘"""
print(" 0 1 2")
for i, row in enumerate(self.board):
print(f"{i} {'|'.join(row)}")
if i < 2:
print(" -----")
print()
# 游戏演示
game = TicTacToe()
print("井字棋游戏开始!")
print("玩家X先手")
moves = [(0, 0), (1, 1), (0, 1), (2, 2), (0, 2)] # 预设移动
for i, (row, col) in enumerate(moves):
if game.make_move(row, col):
print(f"玩家{game.current_player}在位置({row}, {col})下棋")
game.display_board()
if game.game_over:
if game.is_board_full():
print("游戏结束,平局!")
else:
winner = 'O' if game.current_player == 'X' else 'X'
print(f"玩家{winner}获胜!")
break
else:
print(f"无效移动: ({row}, {col})")
break
理解列表操作的性能特征对于编写高效代码很重要:
append()
和 pop()
操作时间复杂度为 O(1)insert()
和 remove()
操作时间复杂度为 O(n)
# 性能对比示例
import time
def measure_time(func, *args):
"""测量函数执行时间"""
start_time = time.time()
result = func(*args)
end_time = time.time()
return result, end_time - start_time
# 测试不同操作的性能
def test_append(n):
lst = []
for i in range(n):
lst.append(i)
return lst
def test_insert(n):
lst = []
for i in range(n):
lst.insert(0, i) # 在开头插入
return lst
def test_extend(n):
lst = []
for i in range(0, n, 1000):
lst.extend(range(i, min(i+1000, n)))
return lst
# 性能测试
n = 10000
print(f"测试规模: {n} 个元素")
print()
_, append_time = measure_time(test_append, n)
print(f"append() 时间: {append_time:.4f} 秒")
_, insert_time = measure_time(test_insert, n)
print(f"insert(0) 时间: {insert_time:.4f} 秒")
_, extend_time = measure_time(test_extend, n)
print(f"extend() 时间: {extend_time:.4f} 秒")
print(f"\ninsert(0) 比 append() 慢 {insert_time/append_time:.1f} 倍")
Python支持函数式编程范式,列表操作可以更加优雅:
# 函数式编程风格的列表操作
from functools import reduce
import operator
# 数据
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
# 使用map进行函数映射
squares = list(map(lambda x: x**2, numbers))
print(f"平方数: {squares}")
# 使用filter进行过滤
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(f"偶数: {evens}")
# 使用reduce进行累积操作
sum_all = reduce(operator.add, numbers)
product_all = reduce(operator.mul, numbers)
print(f"总和: {sum_all}")
print(f"乘积: {product_all}")
# 组合使用
result = reduce(operator.add,
map(lambda x: x**2,
filter(lambda x: x % 2 == 0, numbers)))
print(f"偶数的平方和: {result}")
# 使用itertools模块
from itertools import chain, combinations
# 展平嵌套列表
nested = [[1, 2], [3, 4], [5, 6]]
flattened = list(chain.from_iterable(nested))
print(f"展平结果: {flattened}")
# 生成组合
combs = list(combinations(numbers[:5], 3))
print(f"5个数中取3个的组合数: {len(combs)}")
print(f"前5个组合: {combs[:5]}")
编写健壮的列表操作代码需要适当的错误处理:
# 错误处理示例
def safe_list_operations():
"""演示安全的列表操作"""
# 1. 索引越界处理
try:
lst = [1, 2, 3]
value = lst[10]
except IndexError as e:
print(f"索引错误: {e}")
value = None
# 2. 类型检查
def process_numbers(numbers):
if not isinstance(numbers, list):
raise TypeError("参数必须是列表类型")
if not all(isinstance(x, (int, float)) for x in numbers):
raise ValueError("列表元素必须是数字")
return sum(numbers) / len(numbers)
# 测试类型检查
try:
result = process_numbers([1, 2, 3, "4"])
except (TypeError, ValueError) as e:
print(f"处理错误: {e}")
# 3. 空列表处理
def safe_pop(lst):
"""安全地弹出元素"""
if not lst:
return None
return lst.pop()
# 4. 列表验证
def validate_list_structure(lst, expected_length=None, element_type=None):
"""验证列表结构"""
if not isinstance(lst, list):
return False, "不是列表类型"
if expected_length is not None and len(lst) != expected_length:
return False, f"长度不匹配,期望{expected_length},实际{len(lst)}"
if element_type is not None:
if not all(isinstance(x, element_type) for x in lst):
return False, f"元素类型不匹配,期望{element_type}"
return True, "验证通过"
# 测试验证函数
test_lists = [
[1, 2, 3],
[1, "2", 3],
"not a list",
[1, 2]
]
for test_lst in test_lists:
is_valid, message = validate_list_structure(test_lst, 3, int)
print(f"列表 {test_lst}: {message}")
# 运行错误处理示例
safe_list_operations()
完成以下函数实现:
find_duplicates(lst)
,找出列表中所有重复的元素rotate_list(lst, k)
,将列表向右旋转k个位置flatten_nested(lst)
,将任意深度的嵌套列表展平
# 练习1的参考答案
def find_duplicates(lst):
"""找出列表中所有重复的元素"""
seen = set()
duplicates = set()
for item in lst:
if item in seen:
duplicates.add(item)
else:
seen.add(item)
return list(duplicates)
def rotate_list(lst, k):
"""将列表向右旋转k个位置"""
if not lst:
return lst
k = k % len(lst) # 处理k大于列表长度的情况
return lst[-k:] + lst[:-k]
def flatten_nested(lst):
"""将任意深度的嵌套列表展平"""
result = []
for item in lst:
if isinstance(item, list):
result.extend(flatten_nested(item))
else:
result.append(item)
return result
# 测试函数
test_list = [1, 2, 2, 3, 4, 4, 5]
print(f"重复元素: {find_duplicates(test_list)}")
test_rotate = [1, 2, 3, 4, 5]
print(f"旋转2位: {rotate_list(test_rotate, 2)}")
test_nested = [1, [2, 3], [4, [5, 6]], 7]
print(f"展平结果: {flatten_nested(test_nested)}")
实现以下算法:
quicksort(lst)
binary_search(lst, target)
max_sum_subarray(lst, k)
# 练习2的参考答案
def quicksort(lst):
"""快速排序算法"""
if len(lst) <= 1:
return lst
pivot = lst[len(lst) // 2]
left = [x for x in lst if x < pivot]
middle = [x for x in lst if x == pivot]
right = [x for x in lst if x > pivot]
return quicksort(left) + middle + quicksort(right)
def binary_search(lst, target):
"""二分查找算法(要求列表已排序)"""
left, right = 0, len(lst) - 1
while left <= right:
mid = (left + right) // 2
if lst[mid] == target:
return mid
elif lst[mid] < target:
left = mid + 1
else:
right = mid - 1
return -1
def max_sum_subarray(lst, k):
"""滑动窗口:找出长度为k的子数组的最大和"""
if len(lst) < k:
return None
# 计算第一个窗口的和
current_sum = sum(lst[:k])
max_sum = current_sum
# 滑动窗口
for i in range(k, len(lst)):
current_sum = current_sum - lst[i - k] + lst[i]
max_sum = max(max_sum, current_sum)
return max_sum
# 测试算法
test_numbers = [64, 34, 25, 12, 22, 11, 90]
print(f"原始列表: {test_numbers}")
print(f"快速排序: {quicksort(test_numbers)}")
sorted_numbers = quicksort(test_numbers)
print(f"二分查找25: 索引 {binary_search(sorted_numbers, 25)}")
test_array = [1, 4, 2, 10, 2, 3, 1, 0, 20]
print(f"数组: {test_array}")
print(f"长度为3的子数组最大和: {max_sum_subarray(test_array, 3)}")
实现一个简单的图书管理系统,包含以下功能:
# 练习3的参考答案
class Book:
def __init__(self, title, author, year, genre, pages):
self.title = title
self.author = author
self.year = year
self.genre = genre
self.pages = pages
def __str__(self):
return f"{self.title} by {self.author} ({self.year})"
def to_dict(self):
return {
'title': self.title,
'author': self.author,
'year': self.year,
'genre': self.genre,
'pages': self.pages
}
class Library:
def __init__(self):
self.books = []
def add_book(self, book):
"""添加图书"""
self.books.append(book)
print(f"已添加: {book}")
def remove_book(self, title):
"""根据标题删除图书"""
for i, book in enumerate(self.books):
if book.title.lower() == title.lower():
removed = self.books.pop(i)
print(f"已删除: {removed}")
return True
print(f"未找到图书: {title}")
return False
def find_book(self, title):
"""根据标题查找图书"""
for book in self.books:
if book.title.lower() == title.lower():
return book
return None
def search_by_author(self, author):
"""根据作者查找图书"""
return [book for book in self.books if author.lower() in book.author.lower()]
def sort_books(self, key='title', reverse=False):
"""排序图书"""
if key == 'title':
self.books.sort(key=lambda x: x.title.lower(), reverse=reverse)
elif key == 'author':
self.books.sort(key=lambda x: x.author.lower(), reverse=reverse)
elif key == 'year':
self.books.sort(key=lambda x: x.year, reverse=reverse)
elif key == 'pages':
self.books.sort(key=lambda x: x.pages, reverse=reverse)
def get_statistics(self):
"""获取统计信息"""
if not self.books:
return "图书馆暂无图书"
total_books = len(self.books)
total_pages = sum(book.pages for book in self.books)
avg_pages = total_pages / total_books
genres = {}
years = {}
for book in self.books:
genres[book.genre] = genres.get(book.genre, 0) + 1
years[book.year] = years.get(book.year, 0) + 1
return {
'total_books': total_books,
'total_pages': total_pages,
'avg_pages': avg_pages,
'genres': genres,
'years': years
}
def export_books(self, filename):
"""导出图书列表到文件"""
with open(filename, 'w', encoding='utf-8') as f:
f.write("图书列表\n")
f.write("=" * 50 + "\n")
for i, book in enumerate(self.books, 1):
f.write(f"{i}. {book}\n")
f.write(f" 类型: {book.genre}, 页数: {book.pages}\n\n")
print(f"图书列表已导出到 {filename}")
def display_books(self):
"""显示所有图书"""
if not self.books:
print("图书馆暂无图书")
return
print("\n=== 图书列表 ===")
for i, book in enumerate(self.books, 1):
print(f"{i}. {book}")
print(f" 类型: {book.genre}, 页数: {book.pages}")
# 使用示例
library = Library()
# 添加图书
books_data = [
("Python编程", "张三", 2020, "编程", 300),
("数据结构", "李四", 2019, "计算机科学", 250),
("算法导论", "王五", 2018, "计算机科学", 500),
("机器学习", "赵六", 2021, "人工智能", 400)
]
for title, author, year, genre, pages in books_data:
book = Book(title, author, year, genre, pages)
library.add_book(book)
print("\n" + "="*50)
library.display_books()
print("\n" + "="*50)
print("按年份排序:")
library.sort_books('year', reverse=True)
library.display_books()
print("\n" + "="*50)
stats = library.get_statistics()
print("统计信息:")
for key, value in stats.items():
print(f"{key}: {value}")
# 查找图书
found = library.find_book("Python编程")
if found:
print(f"\n找到图书: {found}")
# 导出图书列表
library.export_books("books.txt")
完成以下编程任务,展示你对Python列表的掌握程度:
列表是Python编程的基础,掌握好列表操作将为后续学习打下坚实基础。建议: