巴音郭楞蒙古自治州网站建设_网站建设公司_Photoshop_seo优化
2026/1/11 1:50:32 网站建设 项目流程

Day 08:【99天精通Python】列表推导式与元组 - 进阶技巧与不可变序列

前言

欢迎来到第8天!

在昨天的课程中,我们掌握了Python中最常用的数据结构——列表(List)的基础用法。你可能已经发现,用for循环来处理列表虽然直观,但有时代码会显得比较拖沓。

Python以"优雅"和"简洁"著称,今天我们将学习列表推导式,这是一种能让你用一行代码搞定复杂列表操作的"魔法"。此外,我们还将介绍列表的"孪生兄弟"——元组(Tuple),看看为什么我们需要一个"不可变"的列表。

本节内容:

  • 列表推导式(List Comprehensions)
  • 元组的创建与操作
  • 元组的解包(Unpacking)
  • 列表 vs 元组:如何选择?
  • 实战练习

一、列表推导式:Pythonic的代码风格

1.1 什么是列表推导式?

列表推导式(List Comprehension)是Python提供的一种简洁的创建列表的方法。它可以将多行循环代码压缩成一行,不仅代码更少,而且执行效率往往更高。

场景对比:我们要创建一个包含1到10平方的列表。

# 普通写法(3行代码)squares=[]forxinrange(1,11):squares.append(x**2)print(squares)# [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]# 列表推导式写法(1行代码)squares=[x**2forxinrange(1,11)]print(squares)

1.2 基本语法

[expressionforiteminiterable]
  • expression:对每个元素执行的操作(生成的元素)。
  • item:从序列中取出的元素。
  • iterable:可迭代对象(如列表、range等)。

1.3 带条件的列表推导式

我们可以在后面加上if语句进行过滤。

语法

[expressionforiteminiterableifcondition]

示例:筛选出1到10之间的偶数,并计算它们的平方。

# 普通写法evens=[]forxinrange(1,11):ifx%2==0:evens.append(x**2)# 列表推导式evens=[x**2forxinrange(1,11)ifx%2==0]print(evens)# [4, 16, 36, 64, 100]

1.4 带if-else的列表推导式

注意:当需要else时,if语句必须放在for之前。

示例:将列表中的偶数保留,奇数变为负数。

numbers=[1,2,3,4,5]# [结果1 if 条件 else 结果2 for 变量 in 列表]new_nums=[xifx%2==0else-xforxinnumbers]print(new_nums)# [-1, 2, -3, 4, -5]

1.5 嵌套列表推导式

推导式也可以嵌套,用于处理二维列表。

示例:将一个 3x3 的矩阵展平为一维列表。

matrix=[[1,2,3],[4,5,6],[7,8,9]]# 普通写法flattened=[]forrowinmatrix:fornuminrow:flattened.append(num)# 推导式写法flattened=[numforrowinmatrixfornuminrow]print(flattened)# [1, 2, 3, 4, 5, 6, 7, 8, 9]

注意:虽然列表推导式很强大,但如果逻辑过分复杂(超过两层循环或复杂判断),为了代码的可读性,建议还是使用普通的for循环。


二、元组(Tuple):不可变的列表

2.1 什么是元组?

元组与列表非常相似,它们都是有序的元素集合。最大的区别在于:元组是不可变的(Immutable)。一旦创建,就不能修改(不能增、删、改元素)。

元组使用小括号()表示。

列表 List

可变 Mutable

使用方括号 []

元组 Tuple

不可变 Immutable

使用小括号 ()

2.2 创建元组

# 创建多个元素的元组t1=(1,2,3)t2=("a","b","c")t3=(1,"hello",3.14)# 混合类型# 省略括号(Python会自动打包)t4=1,2,3print(type(t4))# <class 'tuple'># 创建空元组empty=()# 【重要】创建只有一个元素的元组(必须加逗号)single_wrong=(1)# 这是整数 1single_right=(1,)# 这是元组 (1,)print(type(single_wrong))# <class 'int'>print(type(single_right))# <class 'tuple'>

2.3 访问元组

访问方式与列表完全一致(索引和切片)。

fruits=("苹果","香蕉","橙子","葡萄")print(fruits[0])# 苹果print(fruits[-1])# 葡萄print(fruits[1:3])# ('香蕉', '橙子')

2.4 元组的不可变性

t=(1,2,3)# 尝试修改会报错# t[0] = 10 # TypeError: 'tuple' object does not support item assignment# 尝试添加/删除也会报错# t.append(4) # AttributeError# del t[0] # TypeError

特例:如果元组中包含可变对象(如列表),那么这个列表的内容是可以修改的。

t_mutable=(1,2,["a","b"])t_mutable[2][0]="X"print(t_mutable)# (1, 2, ['X', 'b']) -> 元组本身没变(引用的地址没变),但引用的列表内容变了

三、元组的黑科技:打包与解包

3.1 序列解包(Unpacking)

我们可以将元组(或列表)中的元素一次性赋值给多个变量。

coordinates=(10,20)# 解包x,y=coordinatesprint(x)# 10print(y)# 20# 变量交换(利用解包原理)a=1b=2a,b=b,aprint(a,b)# 2 1

3.2 使用*处理剩余元素

如果变量数量少于元素数量,可以使用*收集剩余元素(结果为列表)。

numbers=(1,2,3,4,5)# 获取首尾,中间打包head,*middle,tail=numbersprint(head)# 1print(middle)# [2, 3, 4]print(tail)# 5# 只获取前两个a,b,*rest=numbersprint(a,b)# 1 2print(rest)# [3, 4, 5]

四、列表 vs 元组

特性列表 (List)元组 (Tuple)
可变性可变 (Mutable)不可变 (Immutable)
符号[]()
速度稍慢稍快(内存占用更小)
用途数据需要频繁修改时数据固定不变、作为字典键值、函数返回多个值
方法丰富 (append, remove…)很少 (count, index)

什么时候用元组?

  1. 数据保护:如果你传递一组数据给函数,且不希望函数修改它,用元组。
  2. 作为字典的键:列表不能做字典的键(因为可变),但元组可以。
  3. 函数返回值:函数返回多个值时,本质上是返回一个元组。

五、实战练习

练习1:列表推导式练手

使用列表推导式完成以下任务:

  1. 生成一个包含 1 到 20 之间所有能被 3 整除的数的列表。
  2. 有一个名字列表names = ["Alice", "Bob", "Charlie", "David"],生成一个新列表,包含每个名字的长度。
# 1. 被3整除nums=[xforxinrange(1,21)ifx%3==0]print(nums)# [3, 6, 9, 12, 15, 18]# 2. 名字长度names=["Alice","Bob","Charlie","David"]name_lengths=[len(name)fornameinnames]print(name_lengths)# [5, 3, 7, 5]

练习2:成绩分析(元组应用)

学生成绩以元组形式存储:(姓名, 分数)
请筛选出及格(>=60)的学生姓名。

students=[("小明",85),("小红",59),("小刚",90),("小强",55)]# 使用列表推导式 + 解包passed_names=[nameforname,scoreinstudentsifscore>=60]print(passed_names)# ['小明', '小刚']

练习3:找出两个列表的共同元素

使用列表推导式找出两个列表中都存在的元素。

list1=[1,2,3,4,5]list2=[4,5,6,7,8]common=[xforxinlist1ifxinlist2]print(common)# [4, 5]

六、常见问题

Q1:元组只有一个元素时为什么要加逗号?

Python中的小括号()既用于元组,也用于数学运算优先级(如(1+2)*3)。如果不加逗号,Python会默认将其解析为数学运算括号或普通对象,而不是元组。

Q2:列表推导式一定会比for循环快吗?

在大多数情况下,列表推导式比等效的for循环要快,因为它是底层的C语言实现的优化。但是,如果逻辑极其复杂,推导式可能会牺牲可读性。可读性优先是Python的哲学。


七、小结

Day 08 进阶技巧

列表推导式

元组 Tuple

[x for x in data if cond]

简洁、高效

不可变序列

打包与解包

作为字典键

关键要点

  1. 列表推导式是用一行代码生成列表的利器。
  2. 元组是不可变的列表,创建单元素元组记得加逗号(1,)
  3. 解包允许我们将序列快速赋值给多个变量,*可以收集剩余元素。
  4. 在数据不需要修改的场景下,优先选择元组。

八、课后作业

  1. 筛选单词:给定一个句子字符串,将其转换为单词列表,然后使用列表推导式筛选出长度大于3的单词。
    • 输入:“Python is an amazing language”
    • 输出:[‘Python’, ‘amazing’, ‘language’]
  2. 元组统计:创建一个包含20个随机整数(1-10)的元组,统计数字 5 出现了多少次,并找出它第一次出现的索引。
  3. 坐标转换:有一个包含多个坐标元组的列表points = [(1, 2), (3, 4), (5, 6)],请使用列表推导式生成一个新的列表,其中每个坐标的 x 和 y 互换位置(即变为[(2, 1), (4, 3), (6, 5)])。

下节预告

Day 09:字典(Dictionary)- Python中最强大的键值对存储结构,我们将解锁数据查询的新姿势!


系列导航

  • 上一篇:Day 07 - 列表基础
  • 下一篇:Day 09 - 字典与集合(待更新)

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询