1.6 Python 列表与元组
前言:序列数据的重要性
在前五篇文章中,我们学习了Python的基本语法、变量与数据类型、运算符以及流程控制。现在,我们将深入探讨Python中最基本且最重要的两种数据结构——列表(List)和元组(Tuple)。它们是Python序列类型的基础,几乎在所有Python程序中都会用到。
列表和元组是存储有序元素集合的容器,它们可以包含任意类型的对象,并且支持丰富的操作和方法。理解它们的特性、区别以及适用场景,对于编写高效、可维护的Python代码至关重要。
本文将全面解析列表和元组的各个方面,通过丰富的实战案例,帮助你深入理解这两种数据结构的原理、操作方法和最佳实践。
一、 序列类型概述
在深入列表和元组之前,我们先来理解什么是序列类型。序列是Python中最基本的数据结构,它具有以下特点:
- 有序性:元素按顺序存储,每个元素都有确定的位置(索引)
- 可迭代:可以使用循环遍历所有元素
- 可切片:支持通过切片操作获取子序列
- 可连接:支持使用
+运算符连接多个序列 - 可重复:支持使用
*运算符重复序列
Python中常见的序列类型包括:
- 列表(List):可变序列
- 元组(Tuple):不可变序列
- 字符串(String):不可变的字符序列
- 范围(Range):不可变的数字序列
二、 列表(List):可变序列
列表是Python中最灵活、最常用的数据结构之一,它可以存储任意类型的元素,并且长度可以动态变化。
2.1 列表的创建与基本操作
实战案例6-1:列表的创建与基本操作
# 创建空列表
empty_list = []
empty_list2 = list()
print(f"空列表: {empty_list}")
# 创建包含元素的列表
numbers = [1, 2, 3, 4, 5] # 整数列表
fruits = ["apple", "banana", "orange"] # 字符串列表
mixed = [1, "hello", 3.14, True] # 混合类型列表
nested = [[1, 2], [3, 4], [5, 6]] # 嵌套列表
print(f"数字列表: {numbers}")
print(f"水果列表: {fruits}")
print(f"混合列表: {mixed}")
print(f"嵌套列表: {nested}")
# 使用list()构造函数创建列表
from_string = list("hello") # ['h', 'e', 'l', 'l', 'o']
from_range = list(range(5)) # [0, 1, 2, 3, 4]
from_tuple = list((1, 2, 3)) # [1, 2, 3]
print(f"从字符串创建: {from_string}")
print(f"从范围创建: {from_range}")
print(f"从元组创建: {from_tuple}")
# 列表的基本操作
# 1. 索引访问
print(f"第一个水果: {fruits[0]}") # apple
print(f"最后一个水果: {fruits[-1]}") # orange (负索引从-1开始)
# 2. 切片操作
print(f"前两个水果: {fruits[0:2]}") # ['apple', 'banana']
print(f"从第二个开始的所有水果: {fruits[1:]}") # ['banana', 'orange']
print(f"每隔一个取一个: {numbers[::2]}") # [1, 3, 5]
print(f"反转列表: {numbers[::-1]}") # [5, 4, 3, 2, 1]
# 3. 检查元素是否存在
print(f"'apple'在列表中: {'apple' in fruits}") # True
print(f"'grape'不在列表中: {'grape' not in fruits}") # True
# 4. 列表长度
print(f"水果列表长度: {len(fruits)}") # 3
2.2 列表的修改操作
列表是可变序列,可以修改其内容。
实战案例6-2:列表的修改操作
# 修改元素
fruits = ["apple", "banana", "orange"]
fruits[1] = "grape" # 修改第二个元素
print(f"修改后的列表: {fruits}") # ['apple', 'grape', 'orange']
# 添加元素
fruits.append("mango") # 在末尾添加
print(f"添加芒果后: {fruits}") # ['apple', 'grape', 'orange', 'mango']
fruits.insert(1, "pear") # 在指定位置插入
print(f"插入梨后: {fruits}") # ['apple', 'pear', 'grape', 'orange', 'mango']
# 扩展列表
more_fruits = ["kiwi", "pineapple"]
fruits.extend(more_fruits) # 添加多个元素
print(f"扩展后: {fruits}") # ['apple', 'pear', 'grape', 'orange', 'mango', 'kiwi', 'pineapple']
# 也可以使用 + 运算符
fruits = fruits + ["watermelon", "cherry"]
print(f"使用+运算符后: {fruits}")
# 使用 * 运算符重复列表
repeated = [1, 2] * 3
print(f"重复列表: {repeated}") # [1, 2, 1, 2, 1, 2]
# 删除元素
removed_fruit = fruits.pop() # 删除并返回最后一个元素
print(f"删除的元素: {removed_fruit}, 剩余列表: {fruits}")
removed_fruit = fruits.pop(2) # 删除指定位置的元素
print(f"删除索引2的元素: {removed_fruit}, 剩余列表: {fruits}")
fruits.remove("pear") # 删除第一个匹配的元素
print(f"删除'pear'后: {fruits}")
del fruits[0] # 删除指定位置的元素
print(f"删除索引0的元素后: {fruits}")
# 清空列表
fruits.clear()
print(f"清空后的列表: {fruits}") # []
2.3 列表的常用方法
列表提供了丰富的内置方法,用于各种操作。
实战案例6-3:列表方法应用
numbers = [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5]
# 计数
count_5 = numbers.count(5)
print(f"数字5出现的次数: {count_5}") # 3
# 查找索引
index_9 = numbers.index(9)
print(f"数字9的索引: {index_9}") # 5
# 如果元素不存在会抛出ValueError
try:
index_7 = numbers.index(7)
except ValueError:
print("数字7不在列表中")
# 从指定位置开始查找
index_5_after_3 = numbers.index(5, 4) # 从索引4开始查找5
print(f"从索引4开始查找5的索引: {index_5_after_3}") # 8
# 排序
numbers.sort() # 默认升序
print(f"升序排序: {numbers}") # [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
numbers.sort(reverse=True) # 降序排序
print(f"降序排序: {numbers}") # [9, 6, 5, 5, 5, 4, 3, 3, 2, 1, 1]
# 使用sorted()函数获取排序后的新列表(不改变原列表)
numbers = [3, 1, 4, 1, 5]
sorted_numbers = sorted(numbers)
print(f"原列表: {numbers}") # [3, 1, 4, 1, 5]
print(f"排序后的新列表: {sorted_numbers}") # [1, 1, 3, 4, 5]
# 反转列表
numbers.reverse()
print(f"反转后的列表: {numbers}") # [5, 1, 4, 1, 3]
# 复制列表
# 浅拷贝
numbers_copy = numbers.copy()
# 等价于
numbers_copy2 = numbers[:]
# 等价于
numbers_copy3 = list(numbers)
print(f"原列表: {numbers}")
print(f"拷贝的列表: {numbers_copy}")
# 修改拷贝不会影响原列表
numbers_copy[0] = 100
print(f"修改拷贝后原列表: {numbers}") # 不变
print(f"修改后的拷贝: {numbers_copy}") # 改变
2.4 列表的遍历与推导式
实战案例6-4:列表遍历与推导式
# 基本遍历
fruits = ["apple", "banana", "orange"]
print("直接遍历元素:")
for fruit in fruits:
print(fruit)
print("\n遍历索引和元素:")
for i, fruit in enumerate(fruits):
print(f"{i}: {fruit}")
# 列表推导式
# 创建平方数列表
squares = [x**2 for x in range(10)]
print(f"平方数列表: {squares}") # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# 带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(f"偶数的平方: {even_squares}") # [0, 4, 16, 36, 64]
# 嵌套循环的列表推导式
pairs = [(x, y) for x in range(3) for y in range(3)]
print(f"坐标对: {pairs}") # [(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
# 使用推导式处理字符串列表
words = ["hello", "world", "python"]
uppercase_words = [word.upper() for word in words]
print(f"大写单词: {uppercase_words}") # ['HELLO', 'WORLD', 'PYTHON']
word_lengths = [len(word) for word in words]
print(f"单词长度: {word_lengths}") # [5, 5, 6]
# 嵌套列表推导式
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flattened = [num for row in matrix for num in row]
print(f"扁平化矩阵: {flattened}") # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# 使用推导式转换数据类型
str_numbers = ["1", "2", "3", "4", "5"]
int_numbers = [int(num) for num in str_numbers]
print(f"转换后的整数: {int_numbers}") # [1, 2, 3, 4, 5]
2.5 列表的深拷贝与浅拷贝
实战案例6-5:列表的拷贝问题
# 浅拷贝问题
original = [[1, 2], [3, 4]]
shallow_copy = original.copy() # 或者 original[:]
# 修改顶层元素
shallow_copy[0] = [5, 6]
print(f"原列表: {original}") # [[1, 2], [3, 4]]
print(f"浅拷贝: {shallow_copy}") # [[5, 6], [3, 4]]
# 修改嵌套元素(会影响原列表)
original = [[1, 2], [3, 4]]
shallow_copy = original.copy()
shallow_copy[0][0] = 99
print(f"原列表: {original}") # [[99, 2], [3, 4]]
print(f"浅拷贝: {shallow_copy}") # [[99, 2], [3, 4]]
# 深拷贝解决方案
import copy
original = [[1, 2], [3, 4]]
deep_copy = copy.deepcopy(original)
deep_copy[0][0] = 99
print(f"原列表: {original}") # [[1, 2], [3, 4]]
print(f"深拷贝: {deep_copy}") # [[99, 2], [3, 4]]
三、 元组(Tuple):不可变序列
元组是不可变序列,一旦创建就不能修改。这种不可变性使得元组在某些场景下比列表更合适。
3.1 元组的创建与基本操作
实战案例6-6:元组的创建与基本操作
# 创建空元组
empty_tuple = ()
empty_tuple2 = tuple()
print(f"空元组: {empty_tuple}")
# 创建包含元素的元组
fruits = ("apple", "banana", "orange") # 标准方式
numbers = 1, 2, 3, 4, 5 # 可以省略括号
single_element = (42,) # 单元素元组必须有逗号
not_a_tuple = (42) # 这不是元组,是整数
print(f"水果元组: {fruits}")
print(f"数字元组: {numbers}")
print(f"单元素元组: {single_element}")
print(f"不是元组: {not_a_tuple} (类型: {type(not_a_tuple)})")
# 使用tuple()构造函数
from_list = tuple([1, 2, 3]) # (1, 2, 3)
from_string = tuple("hello") # ('h', 'e', 'l', 'l', 'o')
print(f"从列表创建: {from_list}")
print(f"从字符串创建: {from_string}")
# 元组的基本操作(与列表类似)
# 索引访问
print(f"第一个水果: {fruits[0]}") # apple
print(f"最后一个水果: {fruits[-1]}") # orange
# 切片操作
print(f"前两个水果: {fruits[0:2]}") # ('apple', 'banana')
# 检查元素是否存在
print(f"'apple'在元组中: {'apple' in fruits}") # True
# 元组长度
print(f"水果元组长度: {len(fruits)}") # 3
# 元组连接和重复
tuple1 = (1, 2, 3)
tuple2 = (4, 5, 6)
combined = tuple1 + tuple2
repeated = tuple1 * 3
print(f"连接后的元组: {combined}") # (1, 2, 3, 4, 5, 6)
print(f"重复的元组: {repeated}") # (1, 2, 3, 1, 2, 3, 1, 2, 3)
3.2 元组的不可变性与优势
实战案例6-7:元组的不可变性
# 尝试修改元组会抛出TypeError
fruits = ("apple", "banana", "orange")
try:
fruits[0] = "grape" # 会失败
except TypeError as e:
print(f"错误: {e}")
# 但是元组可以包含可变对象
mixed_tuple = ([1, 2], [3, 4])
print(f"混合元组: {mixed_tuple}")
# 可以修改元组中的可变对象
mixed_tuple[0][0] = 99
print(f"修改后的混合元组: {mixed_tuple}") # ([99, 2], [3, 4])
# 元组的优势
# 1. 性能更好(创建和访问速度比列表快)
import timeit
list_time = timeit.timeit('x = [1, 2, 3, 4, 5]', number=1000000)
tuple_time = timeit.timeit('x = (1, 2, 3, 4, 5)', number=1000000)
print(f"列表创建时间: {list_time:.6f}秒")
print(f"元组创建时间: {tuple_time:.6f}秒")
print(f"元组比列表快 {list_time/tuple_time:.2f}倍")
# 2. 作为字典的键(因为不可变)
location_dict = {
(40.7128, -74.0060): "New York",
(34.0522, -118.2437): "Los Angeles",
(51.5074, -0.1278): "London"
}
print(f"纽约的坐标: {[k for k, v in location_dict.items() if v == 'New York'][0]}")
print(f"坐标(51.5074, -0.1278)对应的城市: {location_dict[(51.5074, -0.1278)]}")
# 3. 函数返回多个值
def get_stats(numbers):
"""返回数字列表的最小值、最大值和平均值"""
return min(numbers), max(numbers), sum(numbers) / len(numbers)
data = [10, 20, 30, 40, 50]
min_val, max_val, avg_val = get_stats(data)
print(f"最小值: {min_val}, 最大值: {max_val}, 平均值: {avg_val}")
# 4. 保护数据不被修改
CONSTANTS = (3.14159, 2.71828, 1.61803)
# CONSTANTS[0] = 3.14 # 这会失败,保护了常量值
3.3 元组的方法与操作
实战案例6-8:元组的方法
numbers = (3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5)
# 计数
count_5 = numbers.count(5)
print(f"数字5出现的次数: {count_5}") # 3
# 查找索引
index_9 = numbers.index(9)
print(f"数字9的索引: {index_9}") # 5
# 从指定位置开始查找
index_5_after_3 = numbers.index(5, 6) # 从索引6开始查找5
print(f"从索引6开始查找5的索引: {index_5_after_3}") # 8
# 元组解包
person = ("Alice", 25, "New York")
name, age, city = person # 元组解包
print(f"姓名: {name}, 年龄: {age}, 城市: {city}")
# 使用*收集多余的元素
first, *middle, last = numbers
print(f"第一个: {first}, 中间: {middle}, 最后一个: {last}") # 第一个: 3, 中间: [1, 4, 1, 5, 9, 2, 6, 5, 3], 最后一个: 5
# 交换变量的值(使用元组解包)
a, b = 10, 20
print(f"交换前: a={a}, b={b}")
a, b = b, a # 元组解包实现交换
print(f"交换后: a={a}, b={b}")
# 函数参数解包
def print_person(name, age, city):
print(f"{name} is {age} years old and lives in {city}")
person_tuple = ("Bob", 30, "London")
print_person(*person_tuple) # 元组解包作为函数参数
四、 列表与元组的比较与选择
实战案例6-9:列表与元组的比较
# 1. 可变性比较
# 列表是可变的
list_data = [1, 2, 3]
list_data[0] = 100 # 可以修改
list_data.append(4) # 可以添加
print(f"修改后的列表: {list_data}") # [100, 2, 3, 4]
# 元组是不可变的
tuple_data = (1, 2, 3)
# tuple_data[0] = 100 # 会抛出TypeError
# tuple_data.append(4) # 会抛出AttributeError
print(f"元组保持不变: {tuple_data}") # (1, 2, 3)
# 2. 性能比较
import sys
list_obj = [1, 2, 3, 4, 5]
tuple_obj = (1, 2, 3, 4, 5)
print(f"列表占用内存: {sys.getsizeof(list_obj)} 字节")
print(f"元组占用内存: {sys.getsizeof(tuple_obj)} 字节")
# 3. 使用场景总结
"""
使用列表的场景:
- 需要频繁修改、添加或删除元素
- 数据需要动态变化
- 需要丰富的内置方法进行操作
- 数据不需要作为字典的键
使用元组的场景:
- 数据不需要修改,作为常量使用
- 需要作为字典的键
- 函数需要返回多个值
- 性能是关键因素(创建和访问速度)
- 希望保护数据不被意外修改
"""
# 4. 相互转换
# 列表转元组
list_to_tuple = tuple([1, 2, 3])
print(f"列表转元组: {list_to_tuple}") # (1, 2, 3)
# 元组转列表
tuple_to_list = list((1, 2, 3))
print(f"元组转列表: {tuple_to_list}") # [1, 2, 3]
五、 综合实战:员工管理系统
现在,让我们创建一个综合性的员工管理系统,应用本章所学的列表和元组知识。
项目目标:
- 使用元组存储员工信息(ID, 姓名, 部门, 工资)
- 使用列表存储所有员工
- 实现员工信息的增删改查功能
- 提供数据统计和分析功能
- 实现交互式菜单界面
代码实现:
def employee_management_system():
"""员工管理系统"""
employees = [] # 使用列表存储员工元组
while True:
print("\n=== 员工管理系统 ===")
print("1. 添加员工")
print("2. 查看所有员工")
print("3. 查找员工")
print("4. 更新员工信息")
print("5. 删除员工")
print("6. 数据统计")
print("7. 退出系统")
choice = input("请选择操作(1-7): ")
if choice == "1":
add_employee(employees)
elif choice == "2":
view_all_employees(employees)
elif choice == "3":
search_employee(employees)
elif choice == "4":
update_employee(employees)
elif choice == "5":
delete_employee(employees)
elif choice == "6":
show_statistics(employees)
elif choice == "7":
print("感谢使用员工管理系统,再见!")
break
else:
print("无效选择,请重新输入")
def add_employee(employees):
"""添加员工"""
print("\n--- 添加员工 ---")
# 获取员工信息
emp_id = input("请输入员工ID: ")
# 检查ID是否已存在
for emp in employees:
if emp[0] == emp_id:
print("该员工ID已存在")
return
name = input("请输入员工姓名: ")
department = input("请输入部门: ")
# 验证工资输入
while True:
try:
salary = float(input("请输入工资: "))
if salary >= 0:
break
else:
print("工资不能为负数")
except ValueError:
print("请输入有效的数字")
# 创建员工元组并添加到列表
employee = (emp_id, name, department, salary)
employees.append(employee)
print(f"成功添加员工: {name}")
def view_all_employees(employees):
"""查看所有员工"""
if not employees:
print("暂无员工数据")
return
print("\nID\t姓名\t部门\t工资")
print("-" * 40)
for emp in employees:
print(f"{emp[0]}\t{emp[1]}\t{emp[2]}\t{emp[3]:.2f}")
def search_employee(employees):
"""查找员工"""
if not employees:
print("暂无员工数据")
return
search_type = input("按ID查找(1) 按姓名查找(2): ")
if search_type == "1":
emp_id = input("请输入员工ID: ")
found = False
for emp in employees:
if emp[0] == emp_id:
print(f"找到员工: ID={emp[0]}, 姓名={emp[1]}, 部门={emp[2]}, 工资={emp[3]:.2f}")
found = True
break
if not found:
print("未找到该ID的员工")
elif search_type == "2":
name = input("请输入员工姓名: ")
found_employees = [emp for emp in employees if name.lower() in emp[1].lower()]
if found_employees:
print("找到以下员工:")
for emp in found_employees:
print(f"ID={emp[0]}, 姓名={emp[1]}, 部门={emp[2]}, 工资={emp[3]:.2f}")
else:
print("未找到该姓名的员工")
else:
print("无效选择")
def update_employee(employees):
"""更新员工信息"""
if not employees:
print("暂无员工数据")
return
emp_id = input("请输入要更新的员工ID: ")
# 查找员工
for i, emp in enumerate(employees):
if emp[0] == emp_id:
print(f"找到员工: {emp[1]}")
# 获取新信息
name = input(f"请输入新姓名(当前: {emp[1]}): ") or emp[1]
department = input(f"请输入新部门(当前: {emp[2]}): ") or emp[2]
# 验证新工资
while True:
try:
salary_input = input(f"请输入新工资(当前: {emp[3]}): ")
if not salary_input: # 直接回车保持原值
salary = emp[3]
break
salary = float(salary_input)
if salary >= 0:
break
else:
print("工资不能为负数")
except ValueError:
print("请输入有效的数字")
# 更新员工信息(由于元组不可变,需要创建新元组替换旧元组)
employees[i] = (emp_id, name, department, salary)
print("员工信息更新成功")
return
print("未找到该ID的员工")
def delete_employee(employees):
"""删除员工"""
if not employees:
print("暂无员工数据")
return
emp_id = input("请输入要删除的员工ID: ")
for i, emp in enumerate(employees):
if emp[0] == emp_id:
print(f"找到员工: {emp[1]}")
confirm = input("确认删除吗?(y/n): ")
if confirm.lower() == 'y':
del employees[i]
print("员工删除成功")
return
print("未找到该ID的员工")
def show_statistics(employees):
"""显示统计信息"""
if not employees:
print("暂无员工数据")
return
# 计算平均工资
total_salary = sum(emp[3] for emp in employees)
avg_salary = total_salary / len(employees)
print(f"平均工资: {avg_salary:.2f}")
# 找出最高和最低工资
salaries = [emp[3] for emp in employees]
max_salary = max(salaries)
min_salary = min(salaries)
print(f"最高工资: {max_salary:.2f}")
print(f"最低工资: {min_salary:.2f}")
# 按部门统计
departments = {}
for emp in employees:
dept = emp[2]
if dept not in departments:
departments[dept] = []
departments[dept].append(emp[3])
print("\n按部门统计:")
for dept, dept_salaries in departments.items():
dept_avg = sum(dept_salaries) / len(dept_salaries)
print(f"{dept}: {len(dept_salaries)}人, 平均工资: {dept_avg:.2f}")
# 运行系统
if __name__ == "__main__":
employee_management_system()
运行示例:
=== 员工管理系统 ===
1. 添加员工
2. 查看所有员工
3. 查找员工
4. 更新员工信息
5. 删除员工
6. 数据统计
7. 退出系统
请选择操作(1-7): 1
--- 添加员工 ---
请输入员工ID: 1001
请输入员工姓名: 张三
请输入部门: 技术部
请输入工资: 8000
成功添加员工: 张三
=== 员工管理系统 ===
1. 添加员工
2. 查看所有员工
3. 查找员工
4. 更新员工信息
5. 删除员工
6. 数据统计
7. 退出系统
请选择操作(1-7): 1
--- 添加员工 ---
请输入员工ID: 1002
请输入员工姓名: 李四
请输入部门: 市场部
请输入工资: 6000
成功添加员工: 李四
=== 员工管理系统 ===
1. 添加员工
2. 查看所有员工
3. 查找员工
4. 更新员工信息
5. 删除员工
6. 数据统计
7. 退出系统
请选择操作(1-7): 2
ID 姓名 部门 工资
----------------------------------------
1001 张三 技术部 8000.00
1002 李四 市场部 6000.00
=== 员工管理系统 ===
1. 添加员工
2. 查看所有员工
3. 查找员工
4. 更新员工信息
5. 删除员工
6. 数据统计
7. 退出系统
请选择操作(1-7): 6
平均工资: 7000.00
最高工资: 8000.00
最低工资: 6000.00
按部门统计:
技术部: 1人, 平均工资: 8000.00
市场部: 1人, 平均工资: 6000.00
=== 员工管理系统 ===
1. 添加员工
2. 查看所有员工
3. 查找员工
4. 更新员工信息
5. 删除员工
6. 数据统计
7. 退出系统
请选择操作(1-7): 7
感谢使用员工管理系统,再见!
总结与展望
通过本篇文章的深入学习,我们全面掌握了Python中的列表和元组:
-
列表(List):
- 掌握了列表的创建、访问和修改方法
- 学会了列表的常用操作和方法
- 理解了列表推导式的强大功能
- 认识了浅拷贝和深拷贝的区别
-
元组(Tuple):
- 掌握了元组的创建和基本操作
- 理解了元组的不可变性及其优势
- 学会了元组解包和函数参数解包
- 认识了元组的使用场景
-
比较与选择:
- 理解了列表和元组的区别
- 学会了根据场景选择合适的数据结构
- 掌握了它们之间的相互转换
-
综合应用:
- 通过员工管理系统项目,将所学知识融会贯通
- 学会了使用元组存储结构化数据
- 掌握了使用列表管理数据集合
- 实现了完整的数据管理功能
列表和元组是Python编程的基础,几乎所有的Python程序都会用到它们。掌握好这两种数据结构,对于编写高效、可维护的Python代码至关重要。
思考题:
- 在什么情况下应该使用元组而不是列表?反之呢?
- 列表的浅拷贝和深拷贝有什么区别?在什么情况下需要使用深拷贝?
- 元组的不可变性带来了哪些优势?有什么局限性?
- 如何优化大型列表的性能?有哪些最佳实践?
- 在员工管理系统的基础上,还可以添加哪些功能来增强其实用性?
更多推荐


所有评论(0)