3. Python3教程丨一个故事看懂List所有用法:1年级1班的班级生活

本文通过1年级1班的故事介绍Python中的List(列表)基础知识,包括List的定义、特征、创建、计数、访问元素、追加元素、删除、更新、合并、排序与嵌套、复制等操作。通过实例展示了如何在实际场景中运用List的各种功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

List(列表)知识:1年级1班的班级生活

1.1 列表是个啥:List(列表)的基础知识:

今天我们来讲Python六大数据类型的第一种:List(列表)。本文将引入一个1年级1班的班级故事,本故事将贯穿教程始末,力求让每一个小知识点第一次出现在你面前时,都是灵活而可爱的。通过本文的学习后,你就能掌握关于List(列表)的所有相关知识了。那,跟着我一起看下好不啦?

A.List是啥?

a. List属于序列:序列共有 List Turple 字符串 Unicode字符串 buffer对象 xrange对象 六种,所有序列都存在内部的索引(将在后文提及)。

b. List属于标准数据类型:Python标准数据类型共有 Number(数字) String(字符串) List(列表) Turple(元组) Set(集合) Dictionary(字典) 六类。

B.List有啥特征?

我们先来看几个List(序列)长啥样:

>>> a = ['Think','123456','[1,2,3]']

观察可以看到:

a. 序列的基本结构为 变量 = [ ] ,即 变量 = []
b. 序列内的数据类型:不要求一致,可以有多种并存,甚至一个List里面还可以包含其他List。被包含的"子List"此时作为“母List”的元素。
c. 序列内的元素:序列内的内容为元素,元素数目可以为0,即空集 a = [] ;元素之间用 , 分隔开;如果元素为字符串,应用 或者 " 括起来。

C. 序列可以进行的基本操作:最基础的基本操作一共有五种: 索引 切片 检查 ,将在后文中进行详细解释。

1.2 可以对列表做啥:List(列表)的操作

a. 创建:1年级1班开学了!

我们假设1年级1班开学了,一共有李布尔、王多鱼、苏大强三名小朋友入学。我们简称1年级1班的班名为 one ,现在我们要打印出这个班级的同学名单:

>>> one = ['李布尔','王多鱼','苏大强']
>>> one
['李布尔', '王多鱼', '苏大强']

中括号[ ]创建一个列表赋给 one 。当然班级也可以没人,比如隔壁1年级2班没人,list可以是空的:

>>> two = []
>>> two
[]

b. 计数 :班里有几个人?
这时候老师想知道1年级1班有几个人,三个人很容易数出来,可如果想知道全校的人数呢?需要调用 len(班级名) 这个语句来计数列表内的元素长度(数目):

>>> one = ['李布尔','王多鱼','苏大强']
>>> len(one)
3

注意:空list也可以用len,空list长度为0。比如我们看看惨淡的1年级2班:

>>> two = []
>>> len(two)
0

c. 访问元素:班里都是按学号点名的!

在学校里,每名同学都有自己的学号,这就是列表中的元素索引

学号的制定规律:

1.在一个有人的班级中,每名同学都有两个学号(即索引),这个学号是以他们在整个班级中的相对位置确定的。

2.正数第一位学号为 0 ,正数第二位学号为 1 …倒数第一位学号为 -1 ,倒数第二位学号为 -2 。即:正数索引为n-1,倒数索引为-n。

比如以1年级1班为例:

>>> one = ['李布尔','王多鱼','苏大强']

王多鱼是正数第一位同学、倒数第三位同学。所以他的学号就有 0 -3 两个。

当老师想点名的时候,要用 班级名[学号] 的方式点学号。例如点二号同学:

>>> one = ['李布尔','王多鱼','苏大强']
>>> one[2]
'苏大强'

如果老师想知道某个同学的姓氏怎么办?对于列表内的元素我们还可以继续切割:

>>> one = ['李布尔','王多鱼','苏大强']
# 查看 1年级1班 学号为 0 的同学姓名:
>>> name = one[0]
# 取该姓名索引为0的字符:
>>> name [0]
'李'

如果老师想叫多位同学,比如想叫从1号开始后面的所有同学呢?

>>> one = ['李布尔','王多鱼','苏大强']
>>> one[1:]
['王多雨', '苏大强']

我们可以看到,就成功把1号和2号同学叫出来了。这里用的是切片的方式,即 班级名[从第几号学生开始:截止到第几号学生之前] ,从第n号开始的全部可以用 班级名 [n:] ,截止到n号之前的全部可以用 班级名[:n]

d. 追加元素 :1年级1班的新生
班里转来了一名新生,叫史晓明。我们用 班级名.append(新同学名字) 的方式将他添到班级名单里,按照先来后到的规则,他自然排在最后:

第一种情况:默认添加新元素到列表末尾

>>> one = ['李布尔','王多鱼','苏大强']
>>> one.append('史晓明')
>>> one
['李布尔', '王多鱼', '苏大强', '史晓明']

这时候 ‘王多鱼’ 小朋友家财大气粗的派来一名随读保镖,强烈要求学号和王多鱼挨着。那能不能安排到指定位置呢?当然可以,我们可以使用 班级名.insert(保镖学号,‘保镖名字’) 的方式将其添加到指定位置:

第二种情况:指定位置插入元素

>>> one = ['李布尔', '王多鱼', '苏大强', '史晓明']
>>> one.insert(2,'钱大彪')
>>> one
['李布尔', '王多鱼', '钱大彪', '苏大强', '史晓明']

这时候需要注意,因为 ‘钱大彪’ 的加入,导致列表内新元素后面元素的相对位置都发生了一次变化。例如 ‘苏大强’ 过去学号是 2 -2 ,现在学号则变成了 3 -2

e.删除:报告老师,我想退学!

因为刚才 ‘钱大彪’ 的加入,导致 ‘苏大强’ ‘史晓明’ 的学号都滞后一名。在调和失败后, ‘史晓明’ 同学愤而退学,老师只好将其从班级名单中删掉。在python中,将元素从列表中删除一共有三种方式:

第一种删除方式: remove 语句

班主任拿出了班级名单,找到了 ‘史晓明’ 的名字,然后用 班级名.remove(史晓明的姓名) 的方式将 ‘史晓明’ 在班级名单中删除了:

>>> one = ['李布尔', '王多鱼', '钱大彪', '苏大强', '史晓明']
>>> one.remove('史晓明')
>>> one
['李布尔', '王多鱼', '钱大彪', '苏大强']

第二种删除方式: del 语句

第一种用 remove 语句删除的情况,前提是老师记得 ‘史晓明’ 的名字。但万一老师不知道这个学生的名字,或者有熊孩子没事改名字记不住咋办?没事,我们还可以用他的学号删除(索引删除),方法为: del 班级名[史晓明学号]

>>> one = ['李布尔', '王多鱼', '钱大彪', '苏大强', '史晓明']
>>> del one[4]
>>> one
['李布尔', '王多鱼', '钱大彪', '苏大强']

第三种删除方式: pop 语句

我们用学号删除的时候容易出问题,万一删错了咋办?我咋知道哪个索引到底还是不是 ‘史晓明’ 的学号?。这时候我们可以用 pop 语句,同样也是用索引删除,但是pop删除元素后会给你显示删除学号对应的名字。具体方法为: 班级名.pop(史晓明的学号)

>>> one = ['李布尔', '王多鱼', '钱大彪', '苏大强', '史晓明']
>>> one.pop(4)
'史晓明'
>>> one
['李布尔', '王多鱼', '钱大彪', '苏大强']

我们可以看到执行了 班级名.pop(史晓明学号) 后,先给我们返回了一个 ‘史晓明’ 的值,告诉我们刚才删的是啥。我们在执行一下 one ,就会看到班级名单里已经删除了。

注意:当我们需要删除列表中的最后一个元素时,可以不写元素索引。像在刚才的例子中,用 班级名.pop() 即可删除位于班级名单最后的 ‘史晓明’ 同学:

>>> one = ['李布尔', '王多鱼', '钱大彪', '苏大强', '史晓明']
>>> one.pop()
'史晓明'
>>> one
['李布尔', '王多鱼', '钱大彪', '苏大强']

讲完 班级名.remove() del 班级名[] 班级名.pop() 后,不得不将另一种删除元素的语句。这种语句与上述三种的不同在于,它会删除元素内所有元素

第四种删除方式: list.clear() 语句

这种方式为清空列表内所有元素,将该列表变为空list:

>>> a = ('1','2','3')
>>> a.clear()
>>> a
[]

这时候如果我们想再确认一遍 ‘史晓明’ 同学到底还在不在班级名单里,可以使用 in 语句,方法为 要检查的同学名字 in 班级名

>>> one = ['李布尔','王多鱼','钱大彪','苏大强']
>>> '史晓明' in one
False

返回的结果是 False ,就说明史晓明已经不在班级名单中了。同样我们也可以用 要检查的元素 not in 序列 来判断元素是否不再序列中:

>>> one = ['李布尔','王多鱼','钱大彪','苏大强']
>>> '史晓明' not in one
True

这里要注意的是在 要检查的元素 not in 序列 要检查的元素 in 序列 中, in 后面的既可以是 变量 也可以是 序列本身 ,例如:

# 在变量中检索
>>> one = ['李布尔','王多鱼','钱大彪','苏大强']
>>> '史晓明' in one
False

# 在序列中检索
>>> one = ['李布尔','王多鱼','钱大彪','苏大强']
>>> '史晓明' in ['李布尔','王多鱼','钱大彪','苏大强']
False

确定将 ‘史晓明’ 从班级中删除后,班主任想点一遍名。 for in 循环语句终于出场了,用法为 for 标识符 in 序列 。执行语句后,Python会将 列表 中每一个 元素赋值给标识符,赋值结束后继续循环将第二个元素再重新赋值给标识符,直到将列表中所有数据赋过一遍结束。

>>> one = ['李布尔','王多鱼','钱大彪','苏大强']
>>> for i in one:
...     print(i)
...
李布尔
王多鱼
钱大彪
苏大强

在上述代码中,即将序列 one 中的每一个元素依次赋给标识符 i ,即可理解为依次执行: i1 = ‘李布尔’ i2 = ‘王多鱼’ i3 = ‘钱大彪’ i4 = ‘苏大强’,然后 print(i) 即依次打印之前的每一次 i值 ,即依次执行 print(i1) print(i2) print(i3) print(i4)

**f. 更新与替换:王多鱼改名了

换名的情况还是发生了:有一天 ‘王多鱼’ 的家长联系老师,请老师更新一下班级名单,因为王多鱼刚刚改名了。老师问为啥?他说觉得 ‘王多鱼’ 这个名字太世俗了,要取一个有文化的名字: ‘王有才’

老师虽是无奈,也只好作罢。用 班级名[王多鱼的学号] = 王多鱼的新名字 的方式将班级名单中,王多鱼的姓名记录更新了,从此以后王多鱼叫王有才:

>>> one = ['李布尔', '王多鱼', '钱大彪', '苏大强']
>>> one[1] = '王有才'
>>> one
['李布尔', '王有才', '钱大彪', '苏大强']

**g.合并班级

后来教务处做出一个决定,将1年级3班并入1年级1班。忙碌的班主任又要开始重新合并班级名单,我们先来看一下1年级3班的新同学们:

>>> three = ['杨九年','周媛','钱大彪','郑仕']

(好像有个哥们重名了??我们一会再说)

班主任这时调用了 extend 语句合并两个班的学生,方法为 1班名字.extend(3班名字)

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强']
>>> three = ['杨九年','周媛','钱大彪','郑仕']
>>> one.extend(three)
>>> one
['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']

还是按照先来后到的道理:extend里新加入列表内的所有元素,都默认添加到了源列表的末尾。

初次之外还可以用 列表直接相加 的方式,例如:

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强']
>>> three = ['杨九年','周媛','钱大彪','郑仕']
>>> one = one + three
>>> one
['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']

说到列表之间相互相加,我们再顺便谈谈列表的乘法。一个列表可以直接乘以一个数字,我们可以看看会得到什么样的结果:

>>> a = ['think','pad']
>>> a * 3
['think', 'pad', 'think', 'pad', 'think', 'pad']

我们发现:将列表乘以一个整数后,Python会将列表内所有元素按顺序重复输出相应的次数。

另外我们发现,1年级1班和1年级3班都有1名叫 ‘钱大彪’ 的同学,但是都不受影响的就放到了同一个列表中。我们可得知:列表中的元素是可重复的。

如果有重复,我们咋知道重复了几次呢?这时候我们可以用 ‘count’ 语句,用法为 班级名.count(像检查重复数的对象)

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']
>>> one.count('钱大彪')
2

我们就知道,班里现在有两个 ‘钱大彪’ 的人了,我们可以按照学号次序管他们叫 ‘大钱大彪’ 和 ‘小钱大彪’,我们想查 ‘大钱大彪’ 的学号时,可以用 班级名.index(搜索条件) 的方式检索第一个匹配搜索的同学的学号(序列)

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']
>>> one.index('钱大彪')
2

这时候我们就可以快速知道,‘大钱大彪’ 的学号是 2 了。

**h. 排序与嵌套:1年级1班要分组了

为了班级合并后的有序管理,教务处给了1年级1班的班主任一个这样的任务:

  1. 要选出一名班长。
  2. 班长以外的七名同学分成两组,每组一名队长三名队员。
  3. 以学籍号正序为准,前三位分别为:班长、两名队员。
  4. 将班长名单、队长名单、队员名单提交至教务处,收到回复。

第一步:选出学籍号排名第一的同学为班长

一开始我们说每个都学都有自己的学号(索引),但是这容易出现这样一个问题:
在1年级1班里,学号为 0 的是 ‘李布尔’ 小朋友,但 ‘杨九年’ 小朋友在3年级1班的时候学号也是 0 。为了避免这种重新排序,我们要了解 学籍号 (id)这个概念,每个小朋友都有自己独一无二id,我们可以用 id(查看id的对象) 这个语句来查看:

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']
>>> id('苏大强')
2078505060944
>>> id('周媛')
2078503793656

首先要按照学籍号选出班长来。班主任在这时候调用了 min 语句,使用方法为 min(班级名)

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']
>>> min(one)
'周媛'

这时,姓名首字母排名最小的 ‘周媛’ 同学成为了班长。

顺便一提:我们看到 min 语句自然而然就能想到 max 语句,使用方法为 max() 语句。

max min 语句其实可以设定排序条件的,方法为 min(班级名,key=排序方式) ,比如我们想看看1年级1班中谁名字最短,就可以用 len 即长度来作为判断标准 min(班级名,key=len)

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']
>>> min(one,key=len)
'周媛'

我们会发现在班里 ‘周媛’ ‘郑仕’ 都是两个字,但是执行后却给了我们 ‘周媛’ 的名字,原因是: min 或者 max 语句默认将符合条件的第一个作为结果返回。

第二步:按学籍号排名先后分出队长和队员

要分出队长和队员,首先我们要知道1年级1班同学们学籍号由小到大的排序吧,班主任用了 sort 语句给班内人排序,使用方法为 班级名.sort()

>>> one = ['李布尔', '王有才', '钱大彪', '苏大强', '杨九年', '周媛', '钱大彪', '郑仕']
>>> one.sort()
>>> one
['周媛', '李布尔', '杨九年', '王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']

现在就一目了然了: 次序第一位的 ‘周媛’ 为班长、次序第二、三位的 ‘李布尔’ ‘杨九年’ 为队长, 其余五人各为两组队员。

注意:在 sort() 函数中会默认地按升序排列

说到用 sort() 语句可以将一个列表正向排列,就不得不提到可以将列表倒叙排列的 reverse 语句:

>>> one = ['周媛', '李布尔', '杨九年', '王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']
>>> one.reverse()
>>> one
['钱大彪', '钱大彪', '郑仕', '苏大强', '王有才', '杨九年', '李布尔', '周媛']

这时候老师可以创建班长、队长、队员的三个名单了:

>>> monitor = ['周媛']
>>> captain = ['李布尔','杨九年' ]
>>> member = [ '王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']

但是这样分三行显示好像不太方便,机智的班主任使用了将 monitor captain member 合并给了一个新的班级名单:

>>> monitor = '周媛'
>>> captain = ['李布尔','杨九年' ]
>>> member = [ '王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']
>>> one = [monitor, captain, member]
>>> one
['周媛', ['李布尔', '杨九年'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

班主任完成了1年级1班开学以来的第一个重要任务,心满意足的给教务处交了差。

通过上述我们可以观察得知:list(列表)内还可以嵌套其他列表,但其他“列表”被嵌套进来后就已经成为了元素,我们可以检验一下:

>>> one = ['周媛', ['李布尔', '杨九年'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]
>>> len(one)
3

此时再用 len(班级名) 检验发现,one 下只有三个元素。

**i. 复制:教务主任想把这次的名单备个份

教务主任想把这次1年级1班提交的班级名单拷贝一份,留在他的备份 Beifen 里,开始纠结起来了:列表(list)的备份方式有 直接赋值 浅拷贝 深拷贝 三种,这种情况下用哪种好呢?都试试吧!

**第一种拷贝:直接赋值

一开始教务主任想偷偷懒,直接把1年级1班提交的 one 列表赋值给我的备份文件 Beifen 不就好了 :

>>> one = ['周媛', ['李布尔', '杨九年'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]
>>> Beifei = one
>>> Beifei
['周媛', ['李布尔', '杨九年'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

完美!可是直到有一天,教导主任发现他办公室里的那份 Beifen 文件里,怎么 ‘杨九天’ 自己变成了 ‘杨浩天’ ?他去问1年级1班的班主任,班主任告诉他:

杨九天改名了,我就把我手里的班级名单改了,怎么,您那儿的列表也变了?

是的,也改变了:

>>> captain[1] = '杨浩天'
>>> one
[['周媛'], ['李布尔', '杨浩天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]
>>> Beifei
[['周媛'], ['李布尔', '杨浩天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

教务主任想:这不靠谱啊,这样我办公室文件就可以让提交人随便改了!

于是教导主任只能开始尝试第二种:

**第二种拷贝:浅拷贝

浅拷贝的使用方式主要有 拷贝到的地方 = 源列表.copy() 拷贝到的地方 = 源列表[:] 拷贝到的地方 = list(源列表) 效果相同的三种,教导主任就以第一种为例试一下:

>>> Beifei = one.copy()
>>> Beifei
[['周媛'], ['李布尔', '杨九天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

好像看起来又成功了,但教导主任不死心。让班主任再改一下他手里的班级文件,看看自己这里会不会变:

>>> captain[1] = '杨浩天'
>>> one
[['周媛'], ['李布尔', '杨浩天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]
>>> Beifei
[['周媛'], ['李布尔', '杨浩天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

还是会变! 教导主任又放弃了第二种拷贝方式,将希望放在了最后一种上:

**第三种拷贝:深拷贝

深拷贝和刚才两种都不一样,使用深拷贝前需要先用 import 语句将 copy 调用出来,方法为 import copy 。调用后,深拷贝的使用方法为 拷贝到的地方 = copy.deepcopy(源列表)

>>> import copy
>>> Beifei = copy.deepcopy(one)
>>> Beifei
[['周媛'], ['李布尔', '杨九天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

失败了两次的教务主任这时候已经不信结果了,执意要班主任再在他那改一次名字:

>>> captain[1]= '杨浩天'
>>> one
[['周媛'], ['李布尔', '杨浩天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]
>>> Beifei
[['周媛'], ['李布尔', '杨九天'], ['王有才', '苏大强', '郑仕', '钱大彪', '钱大彪']]

成功了!这时候我们就明白了:在深拷贝中,当改变原序列中二层以及二层以下的内容时,拷贝后的内容不会受到任何影响。而直接赋值和浅拷贝的方式会受影响。

啥叫二层?

#这叫只有一层:
first = []
#这叫二层,存在列表嵌套
second = [[],[]]

到这里,我们关于list(列表)的叙述就告一段落。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值