Python快速入门专业版(三十六):Python列表基础:创建、增删改查与常用方法(15+案例)
目录
- 引
- 一、列表的定义与创建:存储任意类型的有序集合
- 1. 基本创建方式
- 2. 使用`list()`函数创建
- 二、列表元素的访问:通过索引操作单个元素
- 1. 访问单个元素
- 2. 访问嵌套列表的元素
- 3. 索引越界错误
- 三、列表元素的增加:动态扩展列表内容
- 1. `append(x)`:在列表末尾添加单个元素
- 2. `insert(index, x)`:在指定位置插入元素
- 3. `extend(lst2)`:合并两个列表(批量添加元素)
- 四、列表元素的删除:移除不需要的元素
- 1. `remove(x)`:根据值删除第一个匹配的元素
- 2. `pop(index)`:根据索引删除元素并返回该元素
- 3. `del`语句:根据索引删除元素(或删除整个列表)
- 4. `clear()`:清空列表中的所有元素
- 五、列表元素的修改:更新已有元素的值
- 1. 修改单个元素
- 2. 批量修改元素(切片赋值)
- 六、列表元素的查询:查找元素的位置与出现次数
- 1. `x in lst`:判断元素是否存在于列表中
- 2. `lst.index(x)`:查找元素的索引位置
- 3. `lst.count(x)`:统计元素出现的次数
- 七、列表的其他常用方法:排序、反转与复制
- 1. `sort()`:对列表进行排序
- 2. `reverse()`:反转列表元素的顺序
- 3. `copy()`:复制列表
- 八、综合案例:用列表实现待办事项管理器
- 案例解析:
- 九、列表使用的注意事项与最佳实践
- 十、总结
引
列表(list)是Python中最常用的数据结构之一,它能存储任意类型的数据(整数、字符串、布尔值等),支持动态修改,是处理有序集合的理想选择。无论是存储用户信息、处理数据集合,还是实现待办事项等功能,列表都能发挥重要作用。
本文将系统讲解列表的基础操作:从创建列表开始,详细介绍增加元素、删除元素、修改元素、查询元素的常用方法,通过15+代码案例演示每个方法的使用场景,并最终实现一个"待办事项管理器"综合案例,帮助你全面掌握列表的实战应用。
一、列表的定义与创建:存储任意类型的有序集合
列表是用方括号[]
包裹的有序元素集合,元素之间用逗号分隔。它的核心特点是:
- 可存储任意类型:同一列表中可以包含整数、字符串、布尔值、甚至其他列表等不同类型的元素。
- 有序性:元素的存储顺序与添加顺序一致,可通过索引访问。
- 可变性:创建后可以动态添加、删除、修改元素。
1. 基本创建方式
# 1. 创建空列表
empty_list = []
print(empty_list) # 输出:[]
print(type(empty_list)) # 输出:<class 'list'># 2. 创建包含元素的列表(同一类型)
numbers = [1, 2, 3, 4, 5] # 整数列表
fruits = ["apple", "banana", "orange"] # 字符串列表# 3. 创建包含混合类型元素的列表(列表的一大特色)
mixed_list = [10, "hello", True, 3.14, [1, 2, 3]]
print(mixed_list) # 输出:[10, 'hello', True, 3.14, [1, 2, 3]]
2. 使用list()
函数创建
list()
函数可以将其他可迭代对象(如字符串、元组、范围对象)转换为列表:
# 将字符串转换为列表(每个字符作为元素)
str_to_list = list("python")
print(str_to_list) # 输出:['p', 'y', 't', 'h', 'o', 'n']# 将元组转换为列表
tuple_to_list = list((1, 2, 3))
print(tuple_to_list) # 输出:[1, 2, 3]# 将范围对象转换为列表
range_to_list = list(range(5)) # range(5) 生成0-4的整数
print(range_to_list) # 输出:[0, 1, 2, 3, 4]
注意:列表中的元素可以是任意类型,但实际开发中建议同一列表存储相同类型的元素(如全是整数或全是字符串),这样更便于后续处理(如排序、筛选)。
二、列表元素的访问:通过索引操作单个元素
列表是有序集合,每个元素都有一个唯一的索引(位置编号),可以通过索引访问或修改元素。Python中索引的规则是:
- 正向索引:从0开始,第一个元素索引为0,第二个为1,以此类推。
- 反向索引:从-1开始,最后一个元素索引为-1,倒数第二个为-2,以此类推。
1. 访问单个元素
fruits = ["apple", "banana", "orange", "grape"]# 正向索引访问
print(fruits[0]) # 输出:apple(第一个元素)
print(fruits[2]) # 输出:orange(第三个元素)# 反向索引访问
print(fruits[-1]) # 输出:grape(最后一个元素)
print(fruits[-3]) # 输出:banana(倒数第三个元素)
2. 访问嵌套列表的元素
当列表中包含其他列表(嵌套列表)时,可以通过多级索引访问内层元素:
# 嵌套列表:学生信息(姓名、年龄、成绩列表)
student = ["Alice", 18, [90, 85, 95]]# 访问外层元素
print(student[0]) # 输出:Alice(姓名)# 访问内层列表的元素(先访问外层索引1的列表,再访问内层索引2的元素)
print(student[2][2]) # 输出:95(成绩列表的第三个元素)
3. 索引越界错误
如果访问的索引超出了列表的范围,会抛出IndexError
异常:
fruits = ["apple", "banana"]
# print(fruits[2]) # 错误:IndexError: list index out of range
# print(fruits[-3]) # 错误:IndexError: list index out of range
技巧:可以通过len()
函数获取列表长度,避免索引越界:
fruits = ["apple", "banana", "orange"]
length = len(fruits) # 获取列表长度(3)
print(fruits[length - 1]) # 安全访问最后一个元素:orange
三、列表元素的增加:动态扩展列表内容
列表的可变性体现在可以随时添加新元素,常用的添加方法有三种:append()
、insert()
和extend()
,分别适用于不同的添加场景。
1. append(x)
:在列表末尾添加单个元素
append()
方法会将元素x
添加到列表的末尾,是最常用的添加方式:
# 案例1:向空列表添加元素
tasks = []
tasks.append("买牛奶") # 末尾添加第一个元素
tasks.append("取快递") # 末尾添加第二个元素
print(tasks) # 输出:['买牛奶', '取快递']# 案例2:添加任意类型的元素
mixed = [1, 2]
mixed.append("hello") # 添加字符串
mixed.append(True) # 添加布尔值
mixed.append([3, 4]) # 添加列表(作为单个元素)
print(mixed) # 输出:[1, 2, 'hello', True, [3, 4]]
注意:append()
每次只能添加一个元素,如果要添加多个元素,需要多次调用。
2. insert(index, x)
:在指定位置插入元素
insert(index, x)
方法会在指定的index
位置插入元素x
,原位置及后面的元素会自动后移:
# 案例1:在列表开头插入元素
fruits = ["banana", "orange"]
fruits.insert(0, "apple") # 在索引0处插入"apple"
print(fruits) # 输出:['apple', 'banana', 'orange']# 案例2:在列表中间插入元素
numbers = [1, 3, 4]
numbers.insert(1, 2) # 在索引1处插入2(原1位置的3及后面元素后移)
print(numbers) # 输出:[1, 2, 3, 4]# 案例3:在列表末尾插入(效果等同于append())
fruits.insert(len(fruits), "grape") # len(fruits)是3,在索引3处插入
print(fruits) # 输出:['apple', 'banana', 'orange', 'grape']
注意:如果index
大于列表长度,元素会被添加到列表末尾;如果index
是负数,会从列表末尾开始计算插入位置。
3. extend(lst2)
:合并两个列表(批量添加元素)
extend()
方法会将另一个列表lst2
中的所有元素逐个添加到当前列表的末尾,相当于批量添加:
# 案例1:合并两个列表
list1 = [1, 2, 3]
list2 = [4, 5, 6]
list1.extend(list2) # 将list2的元素添加到list1末尾
print(list1) # 输出:[1, 2, 3, 4, 5, 6]# 案例2:与append()的区别(关键!)
list3 = [1, 2]
list4 = [3, 4]
list3.append(list4) # 将list4作为单个元素添加
print(list3) # 输出:[1, 2, [3, 4]](长度变为3)list5 = [1, 2]
list5.extend(list4) # 将list4的元素逐个添加
print(list5) # 输出:[1, 2, 3, 4](长度变为4)
总结:
append(x)
:添加单个元素(即使x
是列表,也作为一个元素)。extend(lst2)
:添加多个元素(将lst2
中的元素逐个添加)。insert(index, x)
:在指定位置添加单个元素(灵活但效率低于前两者)。
四、列表元素的删除:移除不需要的元素
列表提供了多种删除元素的方法,适用于不同的删除场景:根据值删除、根据索引删除、清空列表等。
1. remove(x)
:根据值删除第一个匹配的元素
remove(x)
方法会删除列表中**第一个等于x
**的元素,如果x
不存在,会抛出ValueError
:
# 案例1:删除存在的元素
fruits = ["apple", "banana", "apple", "orange"]
fruits.remove("apple") # 删除第一个"apple"
print(fruits) # 输出:['banana', 'apple', 'orange']# 案例2:删除不存在的元素(错误)
# fruits.remove("grape") # 错误:ValueError: list.remove(x): x not in list
2. pop(index)
:根据索引删除元素并返回该元素
pop(index)
方法会删除指定index
位置的元素,并返回被删除的元素(这是它与其他删除方法的重要区别)。如果不指定index
,默认删除最后一个元素:
# 案例1:删除指定索引的元素
numbers = [10, 20, 30, 40]
removed = numbers.pop(1) # 删除索引1的元素(20)
print(numbers) # 输出:[10, 30, 40]
print(removed) # 输出:20(返回被删除的元素)# 案例2:默认删除最后一个元素
last = numbers.pop() # 不指定索引,删除最后一个元素(40)
print(numbers) # 输出:[10, 30]
print(last) # 输出:40
应用场景:pop()
方法因能返回被删除的元素,常用于需要"取出并删除"元素的场景(如栈数据结构的"出栈"操作)。
3. del
语句:根据索引删除元素(或删除整个列表)
del
是Python的关键字,不仅可以删除列表中的元素,还可以删除整个列表:
# 案例1:删除指定索引的元素
colors = ["red", "green", "blue"]
del colors[1] # 删除索引1的元素(green)
print(colors) # 输出:['red', 'blue']# 案例2:删除整个列表
del colors
# print(colors) # 错误:NameError: name 'colors' is not defined(列表已被删除)
del
与pop()
的区别:
del
是语句,没有返回值;pop()
是方法,会返回被删除的元素。del
可以删除整个列表,pop()
只能删除元素。
4. clear()
:清空列表中的所有元素
clear()
方法会删除列表中的所有元素,使列表变为空列表(但列表对象本身仍存在):
tasks = ["买牛奶", "取快递", "写代码"]
tasks.clear() # 清空列表
print(tasks) # 输出:[](空列表)
clear()
与重新赋值的区别:
# 方式1:clear()清空(保留列表对象)
lst1 = [1, 2, 3]
lst1.clear()
print(lst1) # 输出:[](对象仍存在)# 方式2:重新赋值为空列表(创建新的空列表对象)
lst2 = [1, 2, 3]
lst2 = [] # 变量lst2指向新的空列表
五、列表元素的修改:更新已有元素的值
通过索引可以直接修改列表中指定位置的元素,这是列表可变性的直接体现:
1. 修改单个元素
# 案例1:修改普通元素
fruits = ["apple", "banana", "orange"]
fruits[1] = "grape" # 将索引1的元素改为"grape"
print(fruits) # 输出:['apple', 'grape', 'orange']# 案例2:修改嵌套列表的元素
students = [["Alice", 18], ["Bob", 20]]
students[1][1] = 19 # 修改第二个学生的年龄
print(students) # 输出:[['Alice', 18], ['Bob', 19]]
2. 批量修改元素(切片赋值)
通过切片可以一次性修改列表中的多个元素(替换为新的元素序列):
numbers = [1, 2, 3, 4, 5]# 案例1:替换连续的多个元素
numbers[1:4] = [10, 20, 30] # 替换索引1-3的元素(原2,3,4 → 10,20,30)
print(numbers) # 输出:[1, 10, 20, 30, 5]# 案例2:插入多个元素(替换长度为0的切片)
numbers[5:5] = [6, 7] # 在索引5处插入6,7(原列表长度为5,索引5是末尾)
print(numbers) # 输出:[1, 10, 20, 30, 5, 6, 7]# 案例3:删除多个元素(用空列表替换)
numbers[1:3] = [] # 删除索引1-2的元素(10,20)
print(numbers) # 输出:[1, 30, 5, 6, 7]
六、列表元素的查询:查找元素的位置与出现次数
在处理列表时,经常需要查询元素是否存在、元素的索引位置、元素出现的次数等,Python提供了专门的方法实现这些功能。
1. x in lst
:判断元素是否存在于列表中
使用in
关键字可以判断元素x
是否在列表中,返回布尔值(True
存在,False
不存在):
fruits = ["apple", "banana", "orange"]print("apple" in fruits) # 输出:True(存在)
print("grape" in fruits) # 输出:False(不存在)
print("APPLE" in fruits) # 输出:False(区分大小写)
配合not
关键字可以判断元素是否不存在:
print("grape" not in fruits) # 输出:True("grape"不存在)
2. lst.index(x)
:查找元素的索引位置
index(x)
方法返回列表中**第一个等于x
**的元素的索引,如果x
不存在,会抛出ValueError
:
colors = ["red", "green", "blue", "green"]print(colors.index("green")) # 输出:1(第一个"green"的索引)
# print(colors.index("yellow")) # 错误:ValueError: 'yellow' is not in list
还可以指定查找范围(start
和end
参数):
# 从索引2开始查找"green"
print(colors.index("green", 2)) # 输出:3(在索引2及之后的范围内查找)
3. lst.count(x)
:统计元素出现的次数
count(x)
方法返回元素x
在列表中出现的总次数:
numbers = [1, 2, 3, 2, 4, 2, 5]print(numbers.count(2)) # 输出:3(数字2出现了3次)
print(numbers.count(6)) # 输出:0(数字6未出现)
应用场景:统计某个值的频率(如投票结果中各候选人的得票数)。
七、列表的其他常用方法:排序、反转与复制
除了增删改查,列表还有几个常用方法:sort()
(排序)、reverse()
(反转)、copy()
(复制),进一步扩展了列表的功能。
1. sort()
:对列表进行排序
sort()
方法会原地排序列表(直接修改原列表),默认按升序排列:
# 案例1:对数字列表排序
numbers = [3, 1, 4, 2, 5]
numbers.sort() # 升序排序
print(numbers) # 输出:[1, 2, 3, 4, 5]# 案例2:指定降序排序(reverse=True)
numbers.sort(reverse=True) # 降序排序
print(numbers) # 输出:[5, 4, 3, 2, 1]# 案例3:对字符串列表排序(按字母顺序)
fruits = ["banana", "apple", "orange"]
fruits.sort()
print(fruits) # 输出:['apple', 'banana', 'orange']
注意:sort()
方法会修改原列表,如果需要保留原列表,应使用sorted()
函数(返回新的排序后的列表):
original = [3, 1, 2]
sorted_list = sorted(original) # 原列表不变,返回新列表
print(original) # 输出:[3, 1, 2]
print(sorted_list) # 输出:[1, 2, 3]
2. reverse()
:反转列表元素的顺序
reverse()
方法会原地反转列表中元素的顺序(直接修改原列表):
numbers = [1, 2, 3, 4]
numbers.reverse() # 反转列表
print(numbers) # 输出:[4, 3, 2, 1]fruits = ["apple", "banana"]
fruits.reverse()
print(fruits) # 输出:['banana', 'apple']
3. copy()
:复制列表
copy()
方法会创建列表的浅拷贝(新列表,包含原列表的元素引用),修改新列表不会影响原列表(修改嵌套列表中的元素除外):
# 案例1:复制普通列表
original = [1, 2, 3]
copy_list = original.copy() # 创建副本# 修改副本,原列表不变
copy_list[0] = 100
print(original) # 输出:[1, 2, 3]
print(copy_list) # 输出:[100, 2, 3]# 案例2:复制嵌套列表(浅拷贝的局限性)
nested_original = [1, [2, 3]]
nested_copy = nested_original.copy()# 修改嵌套列表中的元素,原列表会受影响(因为浅拷贝只复制外层引用)
nested_copy[1][0] = 200
print(nested_original) # 输出:[1, [200, 3]](原列表被修改)
其他复制方式:
- 使用切片
lst[:]
:copy_list = original[:]
(效果等同于copy()
)。 - 使用
list()
函数:copy_list = list(original)
。
八、综合案例:用列表实现待办事项管理器
结合列表的增删改查方法,实现一个简单的待办事项管理器,支持添加、删除、查看、标记完成等功能:
def todo_manager():"""待办事项管理器:支持添加、删除、查看、标记完成功能"""todos = [] # 存储待办事项的列表,每个元素是字典:{"task": 内容, "done": 是否完成}print("=" * 50)print(" 待办事项管理器")print("功能:")print("1. 添加待办事项")print("2. 删除待办事项(按编号)")print("3. 标记待办事项为已完成(按编号)")print("4. 查看所有待办事项")print("5. 退出")print("=" * 50)while True:choice = input("\n请选择功能(1-5):").strip()if choice == "1":# 1. 添加待办事项task = input("请输入待办事项内容:").strip()if task:# 添加到列表,默认未完成(done=False)todos.append({"task": task, "done": False})print(f"已添加:{task}")else:print("错误:待办事项内容不能为空")elif choice == "2":# 2. 删除待办事项if not todos:print("暂无待办事项,无需删除")continue# 显示所有待办事项供选择print("当前待办事项:")for i, todo in enumerate(todos, 1): # 从1开始编号status = "✓" if todo["done"] else " "print(f"{i}. [{status}] {todo['task']}")try:index = int(input("请输入要删除的编号:")) - 1 # 转换为0-based索引if 0 <= index < len(todos):removed = todos.pop(index)print(f"已删除:{removed['task']}")else:print("错误:编号不存在")except ValueError:print("错误:请输入有效的数字编号")elif choice == "3":# 3. 标记待办事项为已完成if not todos:print("暂无待办事项,无法标记")continue# 显示所有待办事项供选择print("当前待办事项:")for i, todo in enumerate(todos, 1):status = "✓" if todo["done"] else " "print(f"{i}. [{status}] {todo['task']}")try:index = int(input("请输入要标记的编号:")) - 1if 0 <= index < len(todos):todos[index]["done"] = Trueprint(f"已标记完成:{todos[index]['task']}")else:print("错误:编号不存在")except ValueError:print("错误:请输入有效的数字编号")elif choice == "4":# 4. 查看所有待办事项if not todos:print("暂无待办事项")continueprint("\n所有待办事项:")for i, todo in enumerate(todos, 1):status = "✓" if todo["done"] else " "print(f"{i}. [{status}] {todo['task']}")elif choice == "5":# 5. 退出print("感谢使用,再见!")breakelse:print("错误:请输入1-5之间的数字")# 运行待办事项管理器
if __name__ == "__main__":todo_manager()
案例解析:
-
数据存储:用列表
todos
存储待办事项,每个元素是字典{"task": 内容, "done": 是否完成}
,既利用了列表的有序性和动态性,又通过字典存储了每个事项的详细信息。 -
核心功能实现:
- 添加:使用
append()
方法向列表添加新的待办事项字典。 - 删除:通过
pop(index)
方法删除指定索引的待办事项(用户输入的编号需转换为0-based索引)。 - 修改:直接通过索引修改字典的
"done"
值(todos[index]["done"] = True
)。 - 查看:用
enumerate()
函数遍历列表,同时获取编号(从1开始)和元素,格式化输出待办事项及完成状态。
- 添加:使用
-
用户体验:加入了输入验证(如检查空内容、无效编号)和友好提示,确保工具易用性。
九、列表使用的注意事项与最佳实践
-
列表与字符串的区别:
- 列表是可变的(可修改元素),字符串是不可变的(修改会创建新字符串)。
- 列表存储任意类型元素,字符串只存储字符。
-
避免在循环中修改列表长度:
遍历列表时删除或添加元素会导致索引错乱,建议遍历副本或使用切片:# 错误示例:遍历中删除元素导致漏删 numbers = [1, 2, 3, 4] for num in numbers:if num % 2 == 0:numbers.remove(num) print(numbers) # 输出:[1, 3](看似正确,但复杂场景会出错)# 正确示例:遍历副本 numbers = [1, 2, 3, 4] for num in numbers.copy(): # 遍历副本,原列表可安全修改if num % 2 == 0:numbers.remove(num) print(numbers) # 输出:[1, 3]
-
列表的内存效率:
列表会预分配内存空间,频繁添加元素时效率较高;但对于需要频繁插入/删除中间元素的场景,建议使用collections.deque
(双端队列),效率更高。 -
列表推导式:
对于简单的列表创建和转换,推荐使用列表推导式(更简洁高效):# 生成1-10的平方列表 squares = [i**2 for i in range(1, 11)] print(squares) # 输出:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
十、总结
列表是Python中最灵活、最常用的数据结构之一,本文通过15+案例详细讲解了列表的核心操作:
- 创建:用
[]
或list()
函数,支持任意类型元素。 - 增:
append()
(末尾添加)、insert()
(指定位置添加)、extend()
(合并列表)。 - 删:
remove(x)
(按值删除)、pop(index)
(按索引删除并返回)、del
(按索引删除)、clear()
(清空)。 - 改:通过索引直接修改元素,或用切片批量修改。
- 查:
x in lst
(判断存在)、index(x)
(查索引)、count(x)
(查次数)。
通过综合案例"待办事项管理器",我们看到列表如何在实际场景中应用,结合字典等数据结构实现复杂功能。掌握列表的操作是Python入门的重要一步,它将为后续学习更复杂的数据结构(如栈、队列、树)打下坚实基础。