本节课是Python最核心、使用频率最高的数据类型,知识点细节较多,学习完成之后欢迎在评论区留下你的测试代码、疑问,大家一起交流学习!
一、课程前言
前面我们学习了整数、浮点数、字符串、布尔值这类单个存储数据的基础类型。
日常编程经常需要一次性存放一堆数据,例如学生成绩、购物清单、名字集合,这时就要用到 列表 list。
列表属于可变有序容器,也是Python里面最灵活、功能最丰富的数据类型。
二、基础概念详解
1. 什么是列表
列表就是一个可以存放多个元素的有序容器,拥有下面四大核心特性:
1. 有序:元素拥有固定下标顺序,可以通过索引取值
2. 可变:创建之后能够随时增加、删除、修改内部元素
3. 元素类型不受限制:可以存放整数、浮点数、字符串、布尔值,甚至嵌套子列表
4. 允许元素重复:列表里面可以存在多个一模一样的数据
通俗理解:列表就相当于现实当中的购物篮,可以随意往里面放东西、拿出东西、更换物品。
2. 创建列表的两种方式
方式1:方括号 [] 创建(最常用)
# 空列表list1 = []# 存放同种数据fruit = ["苹果", "香蕉", "橙子"]# 存放多种不同类型数据info = ["张三", 18, 175.5, True]# 嵌套列表(二维列表)nest_list = [10, 20, [30, 40]]
方式2:内置函数 list() 转换可迭代对象
可以将字符串、元组、range区间转为列表
# 字符串拆分字符print(list("python"))# 元组转为列表print(list((1,2,3)))# 生成连续数字print(list(range(1,6)))
三、索引取值与切片(高频重点)
1. 正索引、负索引规则
正向下标:从最左侧开始,下标从 0 开始计数
负向下标:从最右侧倒数,最后一位下标为 -1
name = ["小明","小红","小刚","小李"]print(name[0])print(name[-1])
易错细节:列表第一个元素下标永远是0,新手很容易习惯从1开始取值,触发下标越界报错。
2. 切片语法
格式:列表[起始下标:结束下标:步长]
规则:左闭右开,起始位置可取,结束下标不会被截取;切片会生成全新列表,不会改动原列表
num = [10,20,30,40,50,60]print(num[1:4])# 从头截取到下标3print(num[:3])# 从下标2截取到末尾print(num[2:])# 步长为2,隔一位取一个print(num[::2])# 列表反转,生成新列表print(num[::-1])
四、列表增、删、改、查全套代码案例
(一)增加元素三种方法(重点区分)
1. append():在列表尾部添加单个元素
lst = [1,2,3]lst.append(4)print(lst)
注意:追加列表时append会直接把整个嵌套列表当成一个元素
2. extend():批量拆开添加一组数据
lst = [1,2,3]lst.extend([4,5])print(lst)
3. insert(下标,数值):指定下标位置插入元素
lst = [1,2,3]lst.insert(1,99)print(lst)
(二)删除元素四种常用方式
lst = [10,20,30,40,50]# pop:按下标删除,默认删除末尾元素,并且返回被删掉的值lst.pop()# remove:删除第一个匹配的元素lst.remove(20)# del 根据下标删除del lst[0]# clear 清空全部元素lst.clear()
细节:remove只删除第一个相同元素;列表不存在该元素会直接抛出报错。
(三)修改元素
依靠索引直接赋值完成原地修改
fruit = ["苹果","香蕉","橙子"]fruit[1] = "葡萄"print(fruit)
(四)查询元素
lst = [11,22,33,22]# index 获取第一个匹配元素下标,可以限定查找区间print(lst.index(22))# count 统计元素出现次数print(lst.count(22))# in 判断元素是否存在print(33 in lst)
五、列表遍历循环
方式1:直接循环读取元素
food = ["奶茶","蛋糕","饼干"]for i in food: print(i)
方式2:enumerate 同时获取下标和数值
food = ["奶茶","蛋糕","饼干"]for index,val in enumerate(food): print(f"下标{index},数值:{val}")
六、列表内置高级操作、特殊知识点&易错坑点
1. sort() 和 sorted() 的本质区别
- 列表.sort():原地排序,直接修改原始列表,无返回值
- sorted(列表):返回排序后的新列表,原列表不会发生改变
nums = [5,2,8,1]nums.sort()print(nums)nums2 = [5,2,8,1]new_nums = sorted(nums2,reverse=True)print(nums2)print(new_nums)
2. reverse()原地反转 和切片反转
a = [1,2,3]a.reverse()print(a)b = [1,2,3]c = b[::-1]print(b)print(c)
reverse() 修改原列表;切片反转生成新列表
3. 列表拷贝、浅拷贝大坑
列表属于可变对象,普通赋值只是共享同一个内存地址
a = [1,2,3]b = ab[0] = 99print(a)
此时a列表也跟着被改动,因为a、b指向同一块内存。
正确复制新建列表三种写法:
a = [1,2,3]b = a.copy()c = list(a)d = a[:]
深层细节:嵌套列表的时候普通浅拷贝依旧会出现联动修改,复杂嵌套需要使用深拷贝。
4. 可变对象原地修改特性
列表所有增删改操作都是原地修改内存,不会生成新对象;
字符串属于不可变类型,每次改动都会创建全新内存地址。
5. 运算符操作
# 列表相加拼接print([1,2]+[3,4])# 列表重复print([0]*3)
七、课后练习题(共3题)
习题1(基础题)
创建列表 data = [55,66,77,88],使用负索引打印出66;再使用切片截取 [66,77]。
习题2(易错题)
区分append和extend,写出运行结果:
lst = [1,2]lst.append([3,4])print(lst)lst2 = [1,2]lst2.extend([3,4])print(lst2)
习题3(综合实操)
定义成绩列表 score = [88,56,95,72],对列表进行降序排序,并且输出排序之后的列表。
列表细节坑点非常多,例如浅拷贝、下标越界、append和extend混淆。你如果有代码报错或是看不懂的知识点,可以在评论区留言,一起解决问题!