一、列表
列表是由一系元素按特定顺序构成的数据序列,这就意味着如果我们定义一个列表类型的变量,可以用它来保存多个数据。在 Python 中,可以使用[]字面量语法来定义列表,列表中的多个元素用逗号进行分隔
特点:
- 列表中可以有重复元素;
- 列表中可以有不同类型的元素;
二、序列类型-列表
在操作序列类型数据的时候,会经常用到增删改查操作,所以Python给我们提供了一些内置的功能函数:
作用就是帮助我们更好的对数据增删改查。
方法都是固定好的语法,不需要去死记硬背。
用pycharm,有代码补全,如果忘了,翻笔记/查资料。
什么是内置方法: 内置方法是python自带的方法,直接可以使用; 好处:可以用来快速处理数据。
1、列表
1.1 创建列表
在Python中,列表是由一系元素按特定顺序构成的数据序列,这就意味着如果我们定义一个列表类型的变量,可以用它来保存多个数据。在 Python 中,可以使用[]字面量语法来定义列表,列表中的多个元素用逗号进行分隔,代码如下所示。
# 列表:列表是由一系列元素按特定顺序组成的数据序列;
a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9.0, True, 'Hello']
b = ['python', 'java', 'ruby', 'javascript']
c = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(a) # [1, 2, 3, 4, 5, 6, 7, 8, 9, 9, 9.0, True, 'Hello']
print(b) # ['python', 'java', 'ruby', 'javascript']
print(c) # [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
1.2 列表的访问
列表的访问:与字符串一样,列表索引是从0开始,第二个索引是1,依此类推。通过索引列表,可以进行截取、组合等操作。
list4 = ['red', 'green', 'blue', 'yellow', 'white', 'black']

索引也可以从尾部开始,最后一个元素的索引为 -1,往前一位为 -2,以此类推。

使用下标索引来访问列表中的值,同样你也可以使用方括号 [] 的形式截取字符,如下所示:

1.3 特别注意事项
列表中可以有重复元素,例如a中的9;列表中可以有不同类型的元素,例如a中有int类型、float类型、str类型和bool类型的元素,但是我们通常并不建议将不同类型的元素放在同一个列表中,主要是操作起来极为不便。
1.4 list()函数
通过 Python 内置的list()函数将其他序列变成列表。准确的说,list并不是一个普通的函数,它是创建列表对象的构造器,后面会为大家介绍对象和构造器这些概念。
hello = 'Python, Hello!'
d = list(hello)
print(d) # ['P', 'y', 't', 'h', 'o', 'n', ',', ' ', 'H', 'e', 'l', 'l', 'o', '!']
2、列表的方法
列表类型的变量,拥有很多方法,比如增(append()、insert()、extend())、删(pop()、remove()、del、clear())、改(通过索引直接修改)、查(所有的查询方法,里面的内容是显示出来看的,而不是修改的,,所以都要加print)、排序(sort())等等方法。
2.1 增-添加元素
列表是一种可变容器,可变容器指的是我们可以向容器中添加元素、可以向容器中移除元素、也可以向现有容器中修改元素。我们可以使用append()方法向列表中追加元素,使用insert()向列表中插入元素。追加指的是将元素添加到列表的末尾,而插入则是在指定的位置添加新元素。
2.1.1 append()
追加一个数据,添加一个数据到列表的最后一位:
-
列表名.
append(内容) -
food.append('可乐')
2.1.2 insert()
在指定的位置上添加一个数据,原数据会被挤到后面,也就是插队。
-
列表名.
insert(下标,内容) -
food.insert(0,'烤鸭')
2.1.3 extend()
追加一个序列类型,把数据打散/拆分后再添加。
-
列表.
extend(序列内容)【加的数据他可以是单个元素,也可以是列表 元组等等 但是不能是单个数字】 -
food.extend('麻辣烫')
2.1.4 代码示例
# 定义一个列表
food = ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '粑粑柑']
# 列表方法
# 增 append()
# 追加一个元素 “可乐”
food.append('可乐') # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '粑粑柑', '可乐']
print(food)
# 在西瓜后面插入一个元素“钵钵鸡”
food.insert(4, '钵钵鸡') # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '钵钵鸡', '炸鸡', '鸡爪', '粑粑柑', '可乐']
print(food)
# 追加一个序列类型,比如“饺子”
food.extend('饺子') # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '钵钵鸡', '炸鸡', '鸡爪', '粑粑柑', '可乐', '饺', '子']
print(food)
2.2 删-删除元素
我们可以用列表的remove方法从列表中删除指定元素,需要注意的是,如果要删除的元素并不在列表中,会引发ValueError错误导致程序崩溃,所以建议大家在删除元素时,先用之前讲过的成员运算做一个判断。我们还可以使用pop方法从列表中删除元素,pop方法默认删除列表中的最后一个元素,当然也可以给一个位置,删除指定位置的元素。在使用pop方法删除元素时,如果索引的值超出了范围,会引发IndexError异常,导致程序崩溃。除此之外,列表还有一个clear方法,可以清空列表中的元素。
2.2.1 pop()
删除一个值,默认从最后一个元素开始删除,也可以删指定下标。
-
列表.
pop() -
food.pop() # 默认删最后一个元素 -
列表.
pop(下标) -
food.pop(0) # 默认删第一个元素
2.2.2 remove()
删除一个指定的值,如果有多个重复的数据,就从第一个开始删:
-
列表.
remove(数据) -
food.remove('鸡腿')
2.2.3 clear()
清空列表里的所有数据:
-
列表.
clear() -
food.clear()
2.2.4 del删除数据
直接删除变量或者删除变量中的某个值:
-
del变量名 -
del food # 删除food这个变量 -
del列表[下标] -
del food[2] # 删除下标为2的数据
2.2.5 代码示例
# 定义一个列表
food = ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '粑粑柑']
# 列表方法
# 增 append()
# 追加一个元素 “可乐”
food.append('可乐') # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '粑粑柑', '可乐']
print(food)
# 在西瓜后面插入一个元素“钵钵鸡”
food.insert(4, '钵钵鸡') # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '钵钵鸡', '炸鸡', '鸡爪', '粑粑柑', '可乐']
print(food)
# 追加一个序列类型,比如“饺子”
food.extend('饺子') # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '钵钵鸡', '炸鸡', '鸡爪', '粑粑柑', '可乐', '饺', '子']
print(food)
# 定义一个列表
food_list = ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '粑粑柑']
print(food_list) # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '粑粑柑']
# 删除一个值,默认从最后一个数据开始删,也可以删指定下标
food_list.pop()
print(food_list) # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪']
# 删除指定下标的数据,比如删除苹果
food_list.pop(0)
print(food_list) # ['香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪']
# 删除一个指定的值,如果有多个重复的数据.就从第一个开始删 先追加一个苹果、一个粑粑柑、一个炸鸡
food_list.insert(0,'苹果')
food_list.append('苹果')
food_list.append('粑粑柑')
food_list.append('苹果')
food_list.append('粑粑柑')
food_list.append('炸鸡')
print(food_list) # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '炸鸡', '鸡爪', '苹果', '粑粑柑', '苹果', '粑粑柑', '炸鸡']
# 使用remove来删除炸鸡
food_list.remove('炸鸡')
print(food_list) # ['苹果', '香蕉', '珍珠奶茶', '西瓜', '鸡爪', '苹果', '粑粑柑', '苹果', '粑粑柑', '炸鸡']
# 清空列表中的所有数据
# food_list.clear()
print(food_list) # []
# 删除数据.直接删除这个变量或者变量中的值
# del food_list
print(food_list) # 直接报错 NameError: name 'food_list' is not defined
del food_list[0]
print(food_list) # ['香蕉', '珍珠奶茶', '西瓜', '鸡爪', '苹果', '粑粑柑', '苹果', '粑粑柑', '炸鸡']
2.3 改-改列表中的元素
2.3.1 修改单个值
-
列表[下标] = 值
-
food[0] = "洋芋"
2.3.2 修改多个值
-
列表[起点:终点] = 数据1,数据2,数据3,........
-
food[1:4] = '珍珠奶茶','杨枝甘露','草莓奶茶','抹茶拿铁'
2.4 查-查询列表中的元素
所有的查询方法,里面的内容是显示出来看的,而不是修改的,所以都要加print;
-
number=[1,2,5,3,4,68,4,2,6,1,1,66]
2.4.1 index:根据内容,获取指定数据的下标
-
列表.
index(数据) -
-
print(number.index(5)) # 默认从下标为0的位置开始搜索 得到2
-
-
列表.
index(数据,起点下标) -
-
print(number.index(1,2)) # 从起点下标开始找数据 得到9
-
2.4.2 count求和
统计数据出现的次数
-
列表.
count(数据) -
print(number.count(2)) # 得到结果2
2.5 排序
对列表的内容进行排序;如果列表里面有字符串是不可以排序。
-
列表.
sort() -
num.sort() # 默认是升序排序,从小到大 -
列表.
sort(reverse = True) -
num.sort(reverse = True) # 降序排序.从大大小
number = [1, 2, 5, 3, 4, 68, 4, 2, 6, 1, 1, 66]
print(number.index(5)) # 2
print(number.index(1, 2)) # 9
print(number.count(2)) # 2
number1 = number.sort()
print(number1) # None
print(number) # [1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 66, 68]
number2 = number.sort(reverse=True)
print(number2) # None
print(number) # [68, 66, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1]
代码解释:
number1 = number.sort() → None ⚠️
关键陷阱:list.sort() 是原地排序(in-place),返回 None。
number1 = number.sort()
# number 变成了 [1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 66, 68]
# number1 是 None
number2 = number.sort(reverse=True) → None
再次原地排序并反转,number2 依然是 None。此时 number 变为降序:
# number 变为 [68, 66, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1]
| 需求 | 正确写法 | 说明 |
|---|---|---|
| 原地排序,不返回新列表 | number.sort() | 修改原列表,返回 None |
| 返回新列表,不修改原列表 | sorted(number) | 原列表不变,返回排序后的新列表 |
number = [1, 2, 5, 3, 4, 68, 4, 2, 6, 1, 1, 66]
number1 = sorted(number)
print(number1) # [1, 1, 1, 2, 2, 3, 4, 4, 5, 6, 66, 68]
number2 = sorted(number, reverse=True)
print(number2) # [68, 66, 6, 5, 4, 4, 3, 2, 2, 1, 1, 1]
核心要点:sort() 修改列表本身,永远返回 None。要获得排序后的新列表,请使用 sorted()。
2.6 列表方法总结
Python列表常用方法:
| 序号 | 方法 |
|---|---|
| 1 | list.append(obj) 在列表末尾添加新的对象 |
| 2 | list.count(obj) 统计某个元素在列表中出现的次数 |
| 3 | list.extend(seq)在列表末尾一次性追加另一个序列中的多个值(用新列表扩展原来的列表) |
| 4 | list.index(obj)从列表中找出某个值第一个匹配项的索引位置 |
| 5 | list.insert(index, obj)将对象插入列表 |
| 6 | list.pop(index=-1) 移除列表中的一个元素(默认最后一个元素),并且返回该元素的值 |
| 7 | list.remove(obj) 移除列表中某个值的第一个匹配项 |
| 8 | list.reverse()反向列表中元素 |
| 9 | list.sort( key=None, reverse=False)对原列表进行排序 |
| 10 | list.clear()清空列表 |
| 11 | list.copy() 复制列表 |
三、列表的运算
3.1 列表的运算
3.1.1 列表拼接
我们可以使用+运算符实现两个列表的拼接,拼接运算会将两个列表中的元素连接起来放到一个列表中:
items5 = [35, 12, 99, 45, 66]
items6 = [45, 58, 29]
items7 = ['Python', 'Java', 'JavaScript']
print(items5 + items6) # [35, 12, 99, 45, 66, 45, 58, 29]
print(items6 + items7) # [45, 58, 29, 'Python', 'Java', 'JavaScript']
items5 += items6
print(items5) # [35, 12, 99, 45, 66, 45, 58, 29]
3.1.2 列表的重复运算
我们可以使用*运算符实现列表的重复运算,*运算符会将列表元素重复指定的次数:
print(items6 * 3) # [45, 58, 29, 45, 58, 29, 45, 58, 29]
print(items7 * 2) # ['Python', 'Java', 'JavaScript', 'Python', 'Java', 'JavaScript']
3.1.3 判断元素是否在列表中
我们可以使用in或not in运算符,来判断一个元素是否在一个列表中,返回的值是布尔类型:
print(29 in items6) # True
print(99 in items6) # False
print('C++' not in items7) # True
print('Python' not in items7) # False
3.1.4 索引运算
索引运算:由于列表中有多个元素,而且元素按特定顺序放在列表中,所以当我们想操作列表中的某个元素时,可以使用[]运算符,通过在[]中指定元素的位置来访问该元素,这种运算就称为索引运算。
特殊注意:[]的元素位置可以是0到N - 1的整数,也可以是-1到-N的整数,分别称为正向索引和反向索引,其中N代表列表元素的个数。对于正向索引,[0]可以访问列表中的第一个元素,[N - 1]可以访问最后一个元素;对于反向索引,[-1]可以访问列表中的最后一个元素,[-N]可以访问第一个元素。
# 索引运算
item_list = ['Python', 'Java', 'JavaScript', 'apple', 'waxberry', 'pitaya', 'peach']
print(item_list[0]) # Python 访问第一个元素
print(item_list[5]) # pitaya 访问第六个元素
print(len(item_list)) # 7 计算列表item_list的个数
print(item_list[-7]) # Python [-7]可以访问第一个元素
print(item_list[-1]) # peach 访问最后一个元素
在使用索引运算的时候要避免出现索引越界的情况,对于上面的item_list,如果我们访问item_list[9]或item_list[-8],就会引发IndexError错误,导致程序崩溃,对应的错误信息是:list index out of range,翻译成中文就是“数组索引超出范围”。因为对于只有7个元素的列表item_list,有效的正向索引是0到6,有效的反向索引是-1到-7。
3.1.5 切片运算
如果希望一次性访问列表中的多个元素,我们可以使用切片运算。切片运算是形如[start:end:stride]的运算符,其中start代表访问列表元素的起始位置,end代表访问列表元素的终止位置(终止位置的元素无法访问),而stride则代表了跨度,简单的说就是位置的增量,比如我们访问的第一个元素在start位置,那么第二个元素就在start + stride位置,当然start + stride要小于end。我们给上面的代码增加下面的语句,来使用切片运算符访问列表元素。
3.1.5.1 切片访问列表
3.1.5.1.1 切片和索引的关系
在Python中,下标索引和切片是访问序列的两种密切相关但机制不同的方式。
| 概念 | 本质 | 视角 |
|---|---|---|
下标索引 [i] | 指向具体的元素 | "我要第 i 个元素" |
切片 [i:j] | 指向元素之间的边界 | "从边界 i 到边界 j 的元素" |
直观理解:把索引看成“隔板”
想象序列中的元素放在一个个格子中,索引数字式隔板的位置:
0 1 2 3 4 5 6
| P | y | t | h | o | n |
↑ ↑ ↑ ↑ ↑ ↑ ↑
隔板0 隔板1 隔板2 隔板3 隔板4 隔板5 隔板6
下标索引[i] — 访问单个格子:
s = "Python"
s[0] # 'P' → 取隔板0和隔板1之间的元素
s[3] # 'h' → 取隔板3和隔板4之间的元素
切片[start:stop] — 取两个隔板之间的所有元素
s[0:3] # 'Pyt' → 从隔板0到隔板3,包含0不包含3
s[2:5] # 'tho' → 从隔板2到隔板5,包含2不包含5
这就是为什么切片是"左闭右开" [start, stop) 的原因——它描述的是边界范围,而不是元素本身。
关键区别:
nums = [0, 1, 2, 3]
# 索引: 超出范围报错
nums[4] # ❌ IndexError
# 切片: 超出范围不报错,自动截断
nums[2:10] # ✅ [2, 3] (不会报错,取到末尾为止)
nums[5:8] # ✅ [] (空列表,不会报错)
3.1.5.1.2 切片访问列表
item_list = ['Python', 'Java', 'JavaScript', 'apple', 'waxberry', 'pitaya', 'peach']
print(item_list[0:6]) # ['Python', 'Java', 'JavaScript', 'apple', 'waxberry', 'pitaya']
print(item_list[6:9]) # ['peach'] 正向索引,从第六个元素开始访问,到第9-1个元素,因为只有七个元素,顾到列表的最后一个元素
print(item_list[-2:]) # ['pitaya', 'peach'] 反向索引,从索引-2的位置开始访问,到结束,每隔1个进行访问
print(item_list[-4::2]) # ['apple', 'pitaya'] 反向索引,从索引-4的位置开始访问,到结束,每隔2个进行访问
如果start值等于0,那么在使用切片运算符时可以将其省略;如果end值等于N,N代表列表元素的个数,那么在使用切片运算符时可以将其省略;如果stride值等于1,那么在使用切片运算符时也可以将其省略。所以,下面的代码跟上面的代码作用完全相同。
3.1.5.1.3 通过切片修改列表中的元素
# 通过切片修改列表中的元素
item_list[-3:] = ['C', 'Android', 'C++', 'PHP', 'C#']
print(item_list) # ['Python', 'Java', 'JavaScript', 'apple', 'C', 'Android', 'C++', 'PHP', 'C#']
切片:[-3:]也就是从列表元素waxberry开始修改,直到列表中的最后一个元素,按列表item_list的长度7,应该将peach修改为C++就结束,但是切片:有自增元素的功能,也就是将PHP、C++插入到列表item_list中。
3.1.6 关系运算
两个列表还可以做关系运算,我们可以比较两个列表是否相等,也可以给两个列表比大小:
nums1 = [1, 2, 3, 4]
nums2 = list(range(1, 5))
nums3 = [3, 2, 1]
print(nums1 == nums2) # True
print(nums1 != nums2) # False
print(nums1 <= nums3) # True
print(nums2 >= nums3) # False
说明:上面的nums1和nums2对应元素完全相同,所以==运算的结果是True。nums2和nums3的比较,由于nums2的第一个元素1小于nums3的第一个元素3,所以nums2 >= nums3比较的结果是False。两个列表的关系运算在实际工作并不那么常用,如果实在不理解就跳过吧,不用纠结。
四、元素的遍历
如果想逐个取出列表中的元素,可以使用for-in循环的,有以下两种做法。
4.1 循环中通过索引
在循环结构中通过索引运算,遍历列表元素:
# 列表元素遍历
item_list = ['Python', 'Java', 'JavaScript', 'apple', 'C', 'Android', 'C++', 'PHP', 'C#']
language_list = item_list.copy()
print(language_list)
for i in range(len(language_list)):
print(language_list[i])
输出:
Python
Java
JavaScript
apple
C
Android
C
Android
C++
PHP
C#
4.2 做列表循环
直接对列表做循环,循环变量就是列表元素的代表:
# 列表元素遍历
item_list = ['Python', 'Java', 'JavaScript', 'apple', 'C', 'Android', 'C++', 'PHP', 'C#']
language_list = item_list.copy()
print(language_list)
for i in language_list:
print(i)
输出:
Python
Java
JavaScript
apple
C
Android
C
Android
C++
PHP
C#
五、列表生成式
在 Python 中,列表还可以通过一种特殊的字面量语法来创建,这种语法叫做生成式。
5.1 列表生成式
在Python中,列表还可以通过一些特殊的字面量语法来创建,也就是【生成式】,它允许我们以简洁和高效的方式创建列表。下面的是一些列子来说明使用列表生成式,有啥好处;
5.1.1 生成平方数列表
传统方式:
# 定义一个空的列表
squares = []
for i in range(1,8):
squares.append(i ** 2)
print(squares) # 输出:[1, 4, 9, 16, 25, 36, 49]
汉字解释:
- 定义一个空列表
squares;- 使用
for循环来遍历这个左闭右开的整数序列;- 最后使用函数
append()来将这个运算结果i ** 2追加到列表squares中;
使用生成式:
# 使用生成式
squares = [i ** 2 for i in range(1, 8)]
print(squares) # 输出:[1, 4, 9, 16, 25, 36, 49]
汉字解释:
- 使用
for循环遍历range(1,8)(生成1到8的数字);- 对每个数字
i,计算其平方i**2;- 将所有平方结果存储在
squares列表中;
对比:
- 列表生成式将传统
for和append相结合,代码更加简洁; - 列表生成式直接计算所有平方,而传统方式,需要每次迭代调用
append; - 列表生成式更高效,因为它利用了内置函数的优化;
5.1.2 生成奇数列表
传统方式:
# for循环和if的运用
a = []
for i in range(1, 8):
if i % 2 != 0:
a.append(i)
print(a)
# 运行结果:[1, 3, 5, 7]
- 汉字解释:
1、初始化空列表:a = []创建一个空列表用于存储奇数;
2、遍历整数序列range(1, 8):range(1, 8)生成[1, 2, 3, 4, 5, 6, 7]的整数序列;
3、条件判断if i % 2 != 0:如果等于零,则说明是偶数,不将i添加到空列表a中;
4、添加元素:符合条件的数通过append()方法加入列表a中;
5、输出列表a中的数据项:最终列表为[1, 3, 5, 7];
列表生成式(更高效简洁):
- 语法生成式:
[表达式 for 变量 in 可迭代对象 if 条件]
[expression for item in iterable if condition]
- 语法解释:
1、
expression:表达式; 2、item:变量; 3、iterable:可迭代对象; 4、condition:条件; - 代码呈现:
""" 列表生成式"""
a = [x for x in range(1, 8) if x % 2 != 0]
print(a)
"""运行结果:[1, 3, 5, 7]"""
-
列表生成式汉字解释:
1、在
for循环后加if x % 2 != 0,自动过滤奇数;2、好处:逻辑相对而言,减少缩进层级;
5.1.3 嵌套循环(多层for)
生成二维坐标列表的例子: 传统方式:
"""嵌套循环(多层for循环)"""
a = []
for i in range(1, 8):
for j in range(1, 8):
if (i + j) % 2 == 0:
a.append((i, j))
print(a)
"""运行结果:
[(1, 1), (1, 3), (1, 5), (1, 7), (2, 2), (2, 4), (2, 6), (3, 1),
(3, 3), (3, 5), (3, 7), (4, 2), (4, 4), (4, 6), (5, 1), (5, 3),
(5, 5), (5, 7), (6, 2), (6, 4), (6, 6), (7, 1), (7, 3), (7, 5), (7, 7)]
"""
- 汉字解释:
结构特点:显式的多层
for循环,通过控制缩进控制层级,然后使用方法append()追加元素;
核心步骤:
(1)、初始化空列表a;
(2)、外层循环遍历第一个可迭代对象;
(3)、内存循环遍历第二个可迭代对象;
(4)、条件判断后追加元素;
列表生成式:
"""列表生成式"""
a = [
(i, j)
for i in range(1, 8)
for j in range(1, 8)
if (i + j) % 2 == 0
]
print(a)
"""运行结果:
[(1, 1), (1, 3), (1, 5), (1, 7), (2, 2), (2, 4), (2, 6), (3, 1),
(3, 3), (3, 5), (3, 7), (4, 2), (4, 4), (4, 6), (5, 1), (5, 3),
(5, 5), (5, 7), (6, 2), (6, 4), (6, 6), (7, 1), (7, 3), (7, 5), (7, 7)]
"""
- 汉字解释:
结构特点:
隐式嵌套,循环顺序与书写顺序一致(外层 ——> 内层),if条件直接过滤元素。 核心语法:
[元素表达式
for 外层循环 in 外层可迭代对象
for 内层循环 in 内层可迭代对象
if 条件
]
- 性能与可读性对比:
| 特性 | 传统嵌套循环 | 列表生成式嵌套循环 |
|---|---|---|
| 代码长度 | 较长(需显式循环和追加) | 极短(一行代码完成) |
| 执行效率 | 较慢(每次循环调用append()) | 较快(Python底层优化) |
| 可读性 | 高(逻辑分步清晰) | 中(需理解生成式结构) |
| 调试难度 | 易调试(可逐行检查变量) | 难调试(无法逐步跟踪) |
-
列表生成式适用场景:
1、简单数据生成:
如生成矩阵、坐标、笛卡尔积等结构化的数据;2、快速过滤数据:结合条件语句筛选嵌套结构中的元素;
3、代码简洁性优先的场景:需要快速实现且逻辑简单时使用;
-
传统嵌套循环适合:
1、复杂逻辑处理:如需要中间变量、循环内外混合操作;
"""处理多层列表"""
b = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
# 将列表b中的元素,是偶数的挑选出来
# 定义一个空列表
c = []
for i in b:
temp = []
for j in i:
if j % 2 == 0:
temp.append(j)
c.append(temp)
print(c)
# 运行结果:[[2], [4, 6], [8]]
2、调试要求高:需要逐步检查循环中的变量状态时;
3、多层循环嵌套(3层以上):生成式多层嵌套循环可读性差,传统循环更加清晰;
"""列表生成式:生成四维坐标"""
d = [
(x, y, z, j)
for x in range(1,3)
for y in range(1,3)
for z in range(1,3)
for j in range(1,3)
]
print(d)
"""传统方式"""
d = []
for x in range(1,3):
for y in range(1,3):
for z in range(1,3):
for j in range(1,3):
d.append((x, y, z, j))
print(d)
# 由比较可知,传统方式更具可读性
- 输出完美的九九乘法表:
"""九九乘法表"""
# 传统方式
for i in range(1,10):
for j in range(1, i+1):
print(f"{j} * {i} = {i*j:2}", end = " ")
print()
**输出结果**:
1 * 1 = 1
1 * 2 = 2 2 * 2 = 4
1 * 3 = 3 2 * 3 = 6 3 * 3 = 9
1 * 4 = 4 2 * 4 = 8 3 * 4 = 12 4 * 4 = 16
1 * 5 = 5 2 * 5 = 10 3 * 5 = 15 4 * 5 = 20 5 * 5 = 25
1 * 6 = 6 2 * 6 = 12 3 * 6 = 18 4 * 6 = 24 5 * 6 = 30 6 * 6 = 36
1 * 7 = 7 2 * 7 = 14 3 * 7 = 21 4 * 7 = 28 5 * 7 = 35 6 * 7 = 42 7 * 7 = 49
1 * 8 = 8 2 * 8 = 16 3 * 8 = 24 4 * 8 = 32 5 * 8 = 40 6 * 8 = 48 7 * 8 = 56 8 * 8 = 64
1 * 9 = 9 2 * 9 = 18 3 * 9 = 27 4 * 9 = 36 5 * 9 = 45 6 * 9 = 54 7 * 9 = 63 8 * 9 = 72 9 * 9 = 81
- 外层循环 (
i)for i in range(1, 10)控制乘法表的行数- 变量
i表示乘法表中的第二个乘数(即"*"号后面的数字) - 范围1-9对应乘法表的9行
- 内层循环 (
j)for j in range(1, i + 1)控制每行输出的列数- 变量
j表示乘法表中的第一个乘数(即"×"号前面的数字) - 每行的列数等于当前行号(第1行1列,第2行2列...第9行9列)
- 格式化输出
f"{j}*{i}={i*j:2}"使用f-string格式化字符串j×i=显示乘法表达式{i*j:2}将乘积格式化为2位宽度,实现右对齐
end=" "指定每个乘法式后跟两个空格(不换行)
- 换行控制
print()在内层循环结束后执行,实现每行输出后的换行
高级的写法:
"""高级的写法"""
for i in range(1, 10):
# 列表生成式完成
row = [f"{j} x {i} = {i*j:3}" for j in range(1, i + 1)]
# 使用join来将每行的表达式用三个空格连接,确保末尾无多余的空格
print(" ".join(row))
语法解释:
1、外层循环(i):控制行数,从1到9;
2、内层循环(j):控制每行的列数,从1到当前行号i;
3、列表生成式:生成每行的所有乘法表达式,格式为j * i = 结果,使其结果右对齐三位(i * j : 3);
4、字符串拼接:使用join方法将每行的表达式用三个空格连接,确保对齐且无多余的空格;
5、打印输出:每生成一行立即打印,保持格式整齐;
六、列表的总结
1、Python列表方法主要用于动态修改、查询和操作列表。掌握这些方法可以高效处理列表数据。注意区分原地操作(如 sort())与非原地操作(如 sorted() 函数);
2、列表生成式与传统Python程序的写法对比,优缺点;
| 场景 | 传统方式 | 列表生成式 | 核心优势 |
|---|---|---|---|
| 基本遍历 | for + append | [x for x in iterable] | 代码更短,执行更快 |
| 条件过滤 | for + if + append | [x for x in iterable if cond] | 逻辑更清晰 |
| 嵌套循环 | 多层 for | [x for a in A for b in B] | 减少嵌套,代码紧凑 |
| 字符串处理 | for + append | [s.upper() for s in strings] | 减少临时变量 |