抱歉,您的浏览器无法访问本站

本页面需要浏览器支持(启用)JavaScript


了解详情 >

image-20210414220707008

第四章 数据类型:list列表

4.1 列表(序列)的定义

任务一:Python内置数据类型

知识点:

Python内置(build-in)数据类型可以分为数值型非数值型

数值型:整型(int)、浮点型(float)、布尔型(bool) 、复数型 (complex)

非数值型(序列):字符串、列表、元组、字典

知识点:

非数值类都是一个 序列 sequence,也可以理解为容器。它们都支持以下功能:

索引取值**[]**

遍历元素for in

计算序列长度、最大/最小值、比较、删除

拼接+运算符和重复*运算符

切片技术

任务二:认识什么是列表

列表由一系列按特定顺序排列的元素组成。列表是对象,是集合/容器类型的对象

方括号(**[])来表示列表,并用逗号**来分隔其中的元素

下面是一个简单的列表示例,这个列表包含几种自行车:

1
2
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles, type(bicycles))

1、鉴于列表通常包含多个元素,给列表指定一个表示复数的名称(如lettersdigitsnames)是个不错的主意

2、与Java或C的数组区别:

数组的数据类型必须是一样,而列表可以不一样;

数组长度事先声明固定长度,列表长度可增可减

3、Python列表元素可以是任意类型

1
2
3
things = [1, 'car', 4.2, [2, 1]]
print(things, type(things))
print(id(things))

习题:

1、输入你最喜欢的四个朋友,并把她们名字打印(英语名)

2、使用type() 查看类型

3、id() 查看列表引用地址

1
2
3
names = ['James','Kobe','ONeal','Jordan']
print(names, type(names))
print(id(names))
1
2
['James', 'Kobe', 'ONeal', 'Jordan'] <class 'list'>
2203212688320

4.1.1 访问列表元素

任务一:使用索引访问列表元素

列表是有序的容器类数据类型,要访问列表元素,只需将该元素的位置或索引

列表名[索引]。列表的第1个元素索引从0开始。例如,下面的代码从列表bicycles中提取第一款自行车:

1
2
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[3]) #索引值为当前位置-1

当你请求获取列表元素时,Python只返回该元素,而不包括方括号和引号:trek。可以进一步对返回的列表元素调用特定的方法。例如,可使用方法**title()让元素‘trek’**格式更整洁:

1
2
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[0].title(), bicycles[1].upper(), bicycles[2].lower())

这个示例的输出与前一个示例相同,只是首字母T是大写的

任务二:列表的索引

知识点:元素索引

列表的索引0 开始

所谓的索引就是元素在列表中的位置编号,索引又名为下标序号。

从列表中取值时,如果超出索引范围,程序触发异常IndexError

4.1.2 索引访问

任务一:第1个元素的索引是0

知识点:

在Python中,第一个列表元素的索引为0,而不是1

第二个列表元素的索引为1

根据这种简单的计数方式,要访问列表的任何元素,都可将其位置减1,并将结果作为索引

例如,要访问第4个列表元素,可使用索引3

下面的代码访问索引1和3处的自行车,这些代码返回列表中的第二个和第四个元素:

1
2
3
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[1])
print(bicycles[3])

知识点:

Python为列表提供了一种更强大的元素访问机制,切片索引,来获得一个区间索引中的元素

切片索引区间:list[n:m]索引,其中n为起始,m为终止,元素区间**[n,m)**返回索引为n到m-1的元素

1
2
bicycles = ['trek', 'cannondale', 'redline', 'specialized','redline', 'specialized']
print(bicycles[1:])

知识点:

负索引(重要):在不知道列表长度的情况下访问最后的元素

Python为访问最后一个列表元素提供了一种特殊语法

通过将索引指定为**-1,返回最后一个列表元素**

1
2
3
print('---------倒数第一个元素是-1索引---------')
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
print(bicycles[-2])

这些代码返回**’specialized’。这种约定也适用于其他负数索引,例如,索引-2返回倒数第二个列表元素,索引-3**返回倒数第三个列表元素,以此类推

4.1.3 使用列表中的值

任务一:如何使用列表中的元素值

知识点:

使用索引得到的元素进行后续操作。

例如,可以使用拼接根据列表中的值来创建消息

下面来尝试从列表中提取第一款自行车,并使用这个值来创建一条消息:

1
2
3
bicycles = ['trek', 'cannondale', 'redline', 'specialized']
message = "My first bicycle was a " + bicycles[0].title() + "."
print(message)

使用bicycles[0]的值生成了一个句子,并将其存储在变量message中。输出是一个简单的句子,其中包含列表中的第一款自行车:My first bicycle was a Trek.

习题:

1、将一些朋友的姓名存储在一个列表中,并将其命名为names。依次访问该列表中的每个元素,从而将每个朋友的姓名都打印出来

1
2
names = ['James','Kobe','Jordan']
print(names)
1
2
3
James
Kobe
Jordan

2、继续上一题,但不打印每个朋友的姓名,而为每人打印一条消息。每条消息都包含相同的问候语,但抬头为相应朋友的姓名

1
2
3
4
names = ['James','Kobe','Jordan']
print(names[0] + "," + " how is everything going on " + "?")
print(names[1] + "," + " how is everything going on " + "?")
print(names[2] + "," + " how is everything going on " + "?")
1
2
3
James, how is everything going on ?
Kobe, how is everything going on ?
Jordan, how is everything going on ?

3、为朋友输入他们喜欢的交通方式,如骑摩托车或开汽车,并创建一个包含多种交通方式的列表。根据该列表打印一系列有关这些交通方式的宣言,朋友名字和交通工具字符为全大写,如“Lilei would like to own a Honda motorcycle”

1
2
3
4
5
names = ['JAMES','KOBE','JORDAN']
transportations =['BIKE','MOTORCYCLE','CAR']
print(names[0] + " would like to ride a " + transportations[0] + ".")
print(names[1] + " would like to ride a " + transportations[1] + ".")
print(names[2] + " would like to drive a " + transportations[2] + ".")
1
2
3
JAMES would like to ride a BIKE.
KOBE would like to ride a MOTORCYCLE.
JORDAN would like to drive a CAR.

4.1.4 列表的通用操作

4.2(重要)变量内涵

任务一:变量的内涵

变量是Python语言最基本的元素。变量是指向具体数据(对象)的地址引用

1
2
3
a = `python`
b = 1
b = b + 1

变量:门牌号;具体内容:房间

通过赋值(=)语句进行关联

误区:变量中直接存储了具体了数据/对象。程序通过变量来间接访问和操作变量所指的对象

变量中存的地址引用可通过**id()**查看

python内存共享优化机制:

在python中,所有的对象(变量所指向的具体内容)都存活在系统堆上

对于小整数和字符串对象,可能在程序中会经常的使用。如果将这些经常使用的小整数对象也放在系统堆上,python就会经常的在堆上申请空间,释放空间,会严重的影响python的整体性能

对于小整数和字符串(不可变对象)对象做了一些优化,通过使用了对象池技术,将它们驻留在程序缓存中

变量共享引用相同的地址,小整数[-5,256] 和 字符串(不含空格)

1
2
3
a = 'trek1111 111111111111111111111111111111'  
b = 'trek1111 111111111111111111111111111111'
print(id(a), id(b), a is b)
1
2
3
4
5
6
7
8
9
10
11
bicycles1 = ['trek', 'cannondale', 'redline', 'specialized']
bicycles2 = ['trek', 'cannondale', 'redline', 'specialized']
print('bicycles1 id:', id(bicycles1))
print('bicycles2 id:', id(bicycles2))

print('bicycles1[0] id:', id(bicycles1[0])) # 常量字符串共享内存
print('bicycles2[0] id:', id(bicycles2[0]))

print('-------通过is关键字判断两个对象是否是同一个对象(否是来自同个内存地址的数据)----')
print(bicycles1 is bicycles2)
print(bicycles1[0] is bicycles2[0])

4.3 修改、添加和删除列表元素

4.3.1 修改元素

知识点:修改列表元素的语法与访问列表元素的语法类似

首先可指定列表名和要修改的元素的索引

再通过赋值语句,为该元素赋新的值

例如,假设有一个摩托车列表,其中的第一个元素为**’honda’**,如何修改它的值呢?

1
2
3
4
5
6
7
8
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
# ['honda', 'yamaha', 'suzuki']

#motorcycles[0] = [[111,111,111],'hello'] # 列表元素存的是指向具体内容的内存地址!!
motorcycles[0] = 'ducati'
print(motorcycles)
# ['ducati', 'yamaha', 'suzuki']

首先定义一个摩托车列表,其中的第一个元素为**’honda’**

接下来,将第一个元素的值改为**’ducati’**

输出表明,第一个元素的值确实变了,但其他列表元素的值没变

4.3.2 添加元素

补充知识:Python是面向对象编程语言

通俗讲对象就是某种类型的变量

比如字符串对象,整形对象,浮点数对象等

在python中,可以按需求自定义类型,设计新的类

从面向对象OO(Object Oriented)的概念来讲,对象是类的一个实例;类是对象/实例的类型

比如str message,这里的str是类,而message是str类型的对象或str类型的实例

任务一:在列表末尾添加元素append()

知识点:

append()方法用于在列表末尾动态添加新的对象

语法:list.append(obj)

参数:obj为添加到列表末尾的元素

返回:该方法无返回值,直接会修改原来的列表

1
2
3
4
list1 = ['Google', 'Runoob', 'Taobao']
list1.append('Baidu')
print ("更新后的列表 : ", list1)
# 更新后的列表 : ['Google', 'Runoob', 'Taobao', 'Baidu']

例子:继续使用前一个示例中的列表,在其末尾添加新元素**’ducati’。方法append()将元素‘ducati’**添加到了列表末尾,而不影响列表中的其他所有元素

1
2
3
4
motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles.append('ducati')
print(motorcycles)
# ['honda', 'yamaha', 'suzuki', 'ducati']

任务二:创建空列表并动态添加元素

知识点:

经常要等程序运行后,你才知道用户要在程序中存储哪些数据

为控制用户,可首先创建一个空列表,用于存储用户将要输入的值,然后将用户提供的每个新值附加到列表中

此外,方法append()让动态地创建列表易如反掌。例如,可以先创建一个空列表,再使用一系列的append()语句添加元素。下面来创建一个空列表,再在其中添加元素‘honda’‘yamaha’‘suzuki‘,最终的列表与前述示例中的列表完全相同:

1
2
3
4
5
6
7
motorcycles = [] # 创建空列表
motorcycles.append('honda')
print(motorcycles)
motorcycles.append('yamaha')
print(motorcycles)
motorcycles.append('suzuki')
print(motorcycles)

任务三:在列表的指定位置插入新元素insert()

知识点:

insert()方法用于将指定对象插入列表的指定位置。为此,需要指定新元素(对象)的索引和值

语法:list.insert(index, obj)

. 可以看作是该方法的对象作用域。指明该方法仅仅是针对某个具体的list对象进行操作

参数:index为元素obj需要插入的索引位置

参数:obj为添加到列表的元素

返回:该方法无返回值,但会在列表指定位置插入对象

注意:将列表中原索引(包括)之后的所有元素都右移一个位置

1
2
3
4
list1 = ['Google', 'Runoob', 'Taobao']
list1.insert(1, 'Baidu')
print ('列表插入元素后为 : ', list1)
# 列表插入元素后为 : ['Google', 'Baidu', 'Runoob', 'Taobao']

例子:将值**’ducati**’存储到这个地方

1
2
3
4
motorcycles = ['honda', 'yamaha', 'suzuki']
motorcycles.insert(1,'ducati')
print(motorcycles)
# ['honda', 'ducati', 'yamaha', 'suzuki']

4.3.3 删除元素

知识点:

根据位置或值从列表中删除一个或多个元素

玩家将空中的一个外星人射杀后,那么就要将其从存活的外星人列表中删除;

当用户在你创建的Web网站中注销登录的账户时,将该用户从活跃用户列表中删除

任务一:使用del语句删除元素

知识点:

语法:del list[index]

描述:del方法用于将指定位置的列表元素永久删除。为此,需要指定删除元素的索引

del其实并不属于列表的方法或者函数

list[index]为特定列表listindex索引位置的原始

条件:使用del可删除任何位置处的列表元素,条件是知道其索引

注意:del是直接删除list元素内容,无法再访问被删除的元素

例子:使用del删除了列表motorcycles中的第一个元素——**’honda’**

1
2
3
4
5
6
7
8
9
motorcycles = ['honda', 'yamaha', 'suzuki']

del motorcycles[0]
print(motorcycles)
# ['yamaha', 'suzuki']

del motorcycles[0]
print(motorcycles)
# ['suzuki']

任务二:使用方法pop()删除元素

知识点:

语法:obj list.pop([index=-1])

描述:移除列表中的一个元素(默认最后一个元素),并且返回该元素的值

将元素从列表中删除,并接着使用它的值

参数: 带方括号的参数指可选参数

**[index=-1]**可选参数,指明要移除列表元素的索引值,不能超过列表总长度,默认为 index=-1,删除最后一个列表值

返回值: 该方法返回从列表中移除的元素对象obj

例子:下面从列表motorcycles中弹出一款摩托车:

1
2
3
4
5
6
motorcycles = ['honda', 'yamaha', 'suzuki']
popped_motorcycle = motorcycles.pop()
print(motorcycles)
# ['honda', 'yamaha']
print(popped_motorcycle)
# suzuki

分析:

首先定义并打印了列表motorcycles

接下来,我们从这个列表中弹出一个值,并将其存储到变量popped_motorcycle

然后我们打印这个列表,以核实从其中删除了一个值

最后,我们打印弹出的值,以证明我们依然能够访问被删除的值

输出表明,列表末尾的值**’suzuki’已删除,它现在存储在变量popped_motorcycle**中

知识点:

方法**pop()**是怎么起作用的呢?

被删除的元素还有用于他用

假设列表中的摩托车是按购买时间存储的,就可使用方法**pop()**打印一条消息,指出最后购买的是哪款摩托车,输出是一个简单的句子,指出了最新购买的是哪款摩托车:

1
2
3
4
motorcycles = ['honda', 'yamaha', 'suzuki']
last_owned = motorcycles.pop()
print("The last motorcycle I owned was a " + last_owned.title() + ".")
# The last motorcycle I owned was a Suzuki.

任务三:pop()列表中任何位置处的元素

实际上,你可以使用pop()删除列表中任何位置的元素,只需在括号中指定要删除的元素的索引即可

1
2
3
4
5
6
7
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles)
print("---------first_owned = motorcycles.pop(-1)---------")
first_owned = motorcycles.pop(0)
print(motorcycles)
print('The first motorcycle I owned was a ' + first_owned.title() + '.')
# The first motorcycle I owned was a Honda.

首先,弹出列表中的第一款摩托车,然后打印了一条有关这辆摩托车的消息

输出是一个简单的句子,描述了我购买的第一辆摩托车

知识点:

每当使用pop()时,被弹出的元素就不再在列表中了

如果不确定该使用del语句还是**pop()**方法,下面是一个简单的判断标准:

如果你要从列表中删除一个元素,且不再以任何方式使用它,就使用del语句;

如果你要在删除元素后还能继续使用它,就使用方法pop()

任务四:使用remove()方法,根据值删除元素

知识点:

语法:list.remove(obj)

描述:remove()方法用于移除列表中某个值的第一个匹配项

参数: obj为列表中要移除的元素

返回值:该方法没有返回值,但是会移除列表中的某个值的第一个匹配项

条件:只要知道要删除的元素的值

1
2
3
4
5
6
7
8
list1 = ['Google', 'Runoob', 'Taobao', 'Baidu']
list1.remove('Taobao')
print ("列表现在为 : ", list1)
# 列表现在为 : ['Google', 'Runoob', 'Baidu']

list1.remove('Baidu')
print ("列表现在为 : ", list1)
# 列表现在为 : ['Google', 'Runoob']

知识点:**remove()**返回值为空

例子:从列表motorcycles中删除值**’ducati’。通过调用remove()方法,查询‘ducati’**出现在列表的什么地方,并将该元素删除:

1
2
3
4
5
6
motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati']
res = motorcycles.remove('yamaha')
print(motorcycles)
# ['honda', 'suzuki', 'ducati']
print(res)
# None remove()返回值为空

例子:下面删除值**’ducati’**,并打印一条消息,指出要将其从列表中删除的原因

1
2
3
4
5
6
7
motorcycles = ['honda', 'yamaha', 'suzuki', 'ducati', 'yamaha' , 'ducati']
print(motorcycles)

too_expensive = 'ducati' # 该变量为remove()所删除的元素
motorcycles.remove(too_expensive)
print(motorcycles)
print("\nA " + too_expensive.title() + " is too expensive for me.")

定义列表后,我们将值**’ducati’存储在变量too_expensive**中

接下来,我们使用这个变量来告诉Python将哪个值从列表中删除

最后,值**’ducati’已经从列表中删除,但它还存储在变量too_expensive中,让我们能够打印一条消息,指出将‘ducati’从列表motorcycles**中删除的原因

知识点:

remove()删除第一个指定的值

如果要删除的值可能在列表中出现多次,就需要使用循环来判断是否删除了所有这样的值

习题:

1、3-4 嘉宾名单:如果你可以邀请任何人一起共进晚餐(无论是在世的还是故去的),你会邀请哪些人?请创建一个列表,其中包含至少3个你想邀请的人;然后,使用这个列表打印消息,邀请这些人来与你共进晚餐

1
2
3
4
customs = ['James','Kobe','Jordan']
print("Wish " + customs[0] + " would attend my party")
print("Wish " + customs[1] + " would attend my party")
print("Wish " + customs[2] + " would attend my party")
1
2
3
Wish James would attend my party
Wish Kobe would attend my party
Wish Jordan would attend my party

2、3-5 修改嘉宾名单:你刚得知有位嘉宾无法赴约,因此需要另外邀请一位嘉宾

以完成练习3-4 时编写的程序为基础,在程序末尾添加一条print语句,指出哪位嘉宾无法赴约

修改嘉宾名单,将无法赴约的嘉宾的姓名替换为新邀请的嘉宾的姓名

再次打印一系列消息,向名单中的每位嘉宾发出邀请

1
2
3
4
5
6
customs = ['James','Kobe','Jordan']
print(customs[2] + " can`t attend the party")
customs[2] = 'ONeal'
print("Wish " + customs[0] + " would attend my party")
print("Wish " + customs[1] + " would attend my party")
print("Wish " + customs[2] + " would attend my party")
1
2
3
4
Jordan can`t attend the party
Wish James would attend my party
Wish Kobe would attend my party
Wish ONeal would attend my party

3、3-6 添加嘉宾:你刚找到了一个更大的餐桌,可容纳更多的嘉宾。请想想你还想邀请哪三位嘉宾

以完成练习3-4 或练习3-5时编写的程序为基础,在程序末尾添加一条print语句,指出你找到了一个更大的餐桌

使用**insert()**将一位新嘉宾添加到名单开头

使用**insert()**将另一位新嘉宾添加到名单中间

使用**append()**将最后一位新嘉宾添加到名单末尾

打印一系列消息,向名单中的每位嘉宾发出邀请

1
2
3
4
5
6
7
8
9
10
11
12
customs = ['James','Kobe','Jordan']
customs[2] = 'ONeal'
print("I found a bigger table")
customs.insert(0 ,'Curry')
customs.insert(int(len(customs) / 2) ,'Garnett')
customs.append('Davis')
print("Wish " + customs[0] + " would attend my party")
print("Wish " + customs[1] + " would attend my party")
print("Wish " + customs[2] + " would attend my party")
print("Wish " + customs[3] + " would attend my party")
print("Wish " + customs[4] + " would attend my party")
print("Wish " + customs[5] + " would attend my party")
1
2
3
4
5
6
7
I found a bigger table
Wish Curry would attend my party
Wish James would attend my party
Wish Garnett would attend my party
Wish Kobe would attend my party
Wish ONeal would attend my party
Wish Davis would attend my party

4、3-7 缩减名单:你刚得知新购买的餐桌无法及时送达,因此只能邀请两位嘉宾

以完成练习3-6时编写的程序为基础,在程序末尾添加一行代码,打印一条你只能邀请两位嘉宾共进晚餐的消息

使用**pop()**不断地删除名单中的嘉宾,直到只有两位嘉宾为止。每次从名单中弹出一位嘉宾时,都打印一条消息,让该嘉宾知悉你很抱歉,无法邀请他来共进晚餐

对于余下的两位嘉宾中的每一位,都打印一条消息,指出他依然在受邀人之列

使用del将最后两位嘉宾从名单中删除,让名单变成空的。打印该名单,核实程序结束时名单确实是空的

1
2
3
4
5
6
7
8
9
10
11
customs = ['James','Kobe','Jordan']
customs[2] = 'ONeal'
customs.insert(0 ,'Curry')
customs.insert(int(len(customs) / 2) ,'Garnett')
customs.append('Davis')
print("I can only invite two customs to the party")
while len(customs) != 2 :
custom= customs.pop()
print(custom + ", I`m sorry. You can`t attend this party")
del customs[:]
print(customs)
1
2
3
4
5
6
I can only invite two customs to the party
Davis, I`m sorry. You can`t attend this party
ONeal, I`m sorry. You can`t attend this party
Kobe, I`m sorry. You can`t attend this party
Garnett, I`m sorry. You can`t attend this party
[]

4.3.4 将列表用作栈和队列

任务一:将列表用作栈和队列

知识点:列表实现

栈是通常所说的一种LIFO(Last In First Out 后进先出)数据结构

它的意思是最后进入的数据第一个出来

一个最简单的例子往一端封闭的管道放入一些弹珠然后取出来,如果想把弹珠取出来,必须从最后放入弹珠的位置挨个拿出来。

使用**append()**将元素追加到列表尾部

使用 pop() 将最后个的元素弹出列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
a = [1, 2, 3, 4, 5, 6]
print('出栈之前的列表:', a)

print('pop()栈尾部弹出元素:', a.pop())
# pop()栈尾部弹出元素: 6
print('pop()栈尾部弹出元素:', a.pop())
# pop()栈尾部弹出元素: 5
print('pop()栈尾部弹出元素:', a.pop())
# pop()栈尾部弹出元素: 4
print('pop()栈尾部弹出元素:', a.pop())
# pop()栈尾部弹出元素: 3
print('出栈之后的列表:', a)
# 出栈之后的列表: [1, 2]

a.append(34)
print('append()栈尾部加入元素:', a)
# append()栈尾部加入元素: [1, 2, 34]

上面的代码中使用了一个列表的 **pop()append()**方法实现出栈和入栈操作

知识点:列表实现队列

在日常生活中会经常遇到队列,比如售票窗口、图书馆、超市的结账出口

队列 是一种在末尾追加数据以及在开始弹出数据的数据结构

与栈不同,它是 FIFO(First In First Out 先进先出)的数据结构

使用**append()**将元素追加到列表尾部

使用 pop(0) 将第0位置的元素弹出列表

1
2
3
4
5
6
7
8
9
10
11
12
13
a = [1, 2, 3, 4, 5]
print('出栈之前的列表:', a)
# 出栈之前的列表: [1, 2, 3, 4, 5]

a.append(1)
print('append()队列尾部加入元素:', a)
# append()队列尾部加入元素: [1, 2, 3, 4, 5, 1]
print('pop(0)队列首部弹出元素:', a.pop(0))
# pop(0)队列首部弹出元素: 1
print('pop(0)队列首部弹出元素:', a.pop(0))
# pop(0)队列首部弹出元素: 2
print('出队列之后的列表:', a)
# 出队列之后的列表: [3, 4, 5, 1]

4.4 列表的排序

4.4.1 list.sort()方法进行永久性排序

任务一:列表的永久排序

所谓永久性排序,指调用**list.sort()**方法会改变原列表

知识点:

描述:list.sort()方法用于对列表进行排序;默认情况下,sort()方法对列表进行(ascending)升序排序;还可以通过自定义比较函数来设置排序规则

语法:list.sort(reverse=False|True, key=myFunc)

参数:

reverse – 可选。reverse=True 将对列表进行降序排序。默认是 reverse=False

key – 可选。指定排序标准的函数

返回值:该方法没有返回值

该排序方法会修改了列表list元素的排列顺序

1
2
3
4
5
6
# vowels list
vowels = ['e', 'a', 'u', 'o', 'i']
print('排序前的list:', vowels)

vowels.sort()
print('排序后的list:', vowels)

例子:假设你有一个汽车列表,并要让其中的汽车按字母顺序排列。为简化这项任务,假设该列表中的所有值都是小写的

1
2
3
4
5
6
7
8
9
10
11
cars = ['toyota', 'subaru', 'abmw', 'abudi']
print(cars)

print('------------cars.sort()--------------')
print('------通过print(cars)发现sort()方法永久改变原列表------------')
cars.sort()
print(cars)

print('------------cars.sort(reverse=True) 降序排列--------------')
cars.sort(reverse=True)
print(cars)

方法sort()永久性地修改了列表元素的排列顺序。现在,汽车是按字母顺序排列的,再也无法恢复到原来的排列顺序

还可以按与字母顺序相反的顺序排列列表元素,为此,只需向sort()方法传递参数reverse=True

任务二:通过sort()的参数key,自定义排序规则

例子:按照值的长度对列表进行排序:

1
2
3
4
5
6
7
8
9
10
11
12
# 定义函数:返回值为元素的长度
def myFunc(e): #e为形参
return len(e)

cars = ['toyotaa', 'subaru', 'abmw', 'abudi']
print('原来的list:', cars)

cars.sort(key=myFunc)
print('排序(升序)后的list', cars)

cars.sort(reverse=True, key=myFunc)
print('排序(降序)后的list', cars)

例子:按二维数组的第二个元素值进行排序

1
2
3
4
5
6
7
8
def takeSecond(elem):
return elem[1]

digits = [[2, 2], [3, 4], [4, 1], [1, 3]]
print('排序前的list:', digits)

digits.sort(key=takeSecond)
print('排序后的list:', digits)

练习:

1、输入5个数,存到列表中,然后使用**sort()**,对该列表进行按升序、降序进行排序,并输出结果

1
2
3
4
5
6
numbers = ['3', '1', '4', '2', '5']
print(numbers)
numbers.sort()
print(numbers)
numbers.sort(reverse=True)
print(numbers)
1
2
3
['3', '1', '4', '2', '5']
['1', '2', '3', '4', '5']
['5', '4', '3', '2', '1']

2、构造拥有5个城市名字元素的列表cities,然后使用**sort()**,对该列表进行按升序、降序、字符串长度方式进行排序,并输出结果

1
2
3
4
5
citis = ['China', 'America', 'Canada', 'England','Japan']
another_city = sorted(citis)
print('sorted()排序后(升序默认):',another_city)
another_city.sort(reverse = True)
print('list.sort()排序后(降序):',another_city)
1
2
sorted()排序后(升序默认): ['America', 'Canada', 'China', 'England', 'Japan']
list.sort()排序后(降序): ['Japan', 'England', 'China', 'Canada', 'America']

4.4.2 sorted()函数进行临时排序

任务一:列表的临时排序

list.sort()方法是将排序结果覆盖修改原列表

新需求:希望得到列表的排序,但而不希望对原列表进行修改。函数**sorted()**让我们能够对列表进行元素排序(返回一个新的临时列表),但不影响原始排列顺序

知识点:

描述: sorted() 函数对所有可迭代的对象进行排序操作

语法:sorted(iterable, key=None, reverse=False)

参数:

iterable – 可迭代对象。通俗讲是该对象的元素是可以被循环遍历的。通常是集合或序列类型,比如list, str

key – 可选。指定排序标准的函数

reverse – 可选。reverse=True 将对列表进行降序排序。默认是 reverse=False

返回值:返回重新排序的列表(与原列表无关)

注意:传进去的是可迭代对象,而返回的是列表(非原来对象类型)

1
2
3
4
5
6
7
8
9
# list 列表对象
py_list = ['e', 'a', 'u', 'o', 'i']
print('排序前:', py_list)
print('排序后:', sorted(py_list))

# string 字符串对象
py_string = 'Python'
print('排序前:', py_string)
print('排序后:', sorted(py_string, reverse=True))

任务二:自定义排序规则

**sorted()**函数的第二个元素的值为自定义排序规则

1
2
3
4
5
6
7
def takeSecond(elem):
return elem[1]

digits = [[2, 2], [3, 4], [4, 1], [1, 3]]
print('排序前:', digits)
print('排序后:', sorted(digits, key=takeSecond))
print('原来列表:', digits)
1
2
3
4
5
6
7
8
9
10
11
cars = ['bmw', 'audi', 'toyota', 'subaru']

print('排序前:',cars) #按原始顺序打印列表

another_car = sorted(cars) #调用sorted(),按字母顺序排序列表
print('sorted()排序后(升序默认):',another_car)

another_car.sort(reverse = True) #调用sorted(),按字母降序排序列表
print('list.sort()排序后(降序):',another_car)

print('原列表, sorted()并不改变原列表:',cars)

任务三:sorted()是python的一个全局函数

知识点:

sorted()是python的一个全局函数,不是list的方法,因此不能通过**list.sorted()**方式调用

方法:属于对象的函数

函数:全局函数

1
2
print("------------不能通过cars.sorted()-------------")
print(cars.sorted())

4.4.3 list.reverse()方法对列表进行逆序

要反转列表元素的排列顺序,可使用方法list.reverse()

知识点:

描述:**list.reverse()**方法反转元素的排序顺序

语法:list.reverse()

参数:无

返回值:无

注意:永久性的修改原列表

假设汽车列表是按购买时间排列的,可轻松地按相反的顺序排列其中的汽车:

1
2
3
4
5
6
7
8
cars = ['bmw', 'audi', 'toyota', 'subaru']
print('原列表:', cars)

cars.reverse()
print('reverse()后的列表:',cars)

cars.reverse()
print('再次reverse()后的列表:',cars)

知识点:

reverse()不是指按与字母顺序相反的顺序排列列表元素,而只是反转列表元素的排列顺序

方法reverse()永久性地修改列表元素的排列顺序,但可随时恢复到原来的排列顺序,为此只需对列表再次调用**reverse()**即可

习题:

1、创建一个列表,通过**reverse()**对元素顺序进行翻转,再恢复原来的排序

1
2
3
4
5
6
names = ['James', 'Kobe', 'Jordan', 'ONeal']
print('原列表:', names)
names.reverse()
print('reverse()后的列表:',names)
names.reverse()
print('再次reverse()后的列表:',names)
1
2
3
原列表: ['James', 'Kobe', 'Jordan', 'ONeal']
reverse()后的列表: ['ONeal', 'Jordan', 'Kobe', 'James']
再次reverse()后的列表: ['James', 'Kobe', 'Jordan', 'ONeal']

2、输入多个字符串,存在列表中,然后调用**reverse()**对元素顺序进行翻转,并输出结果

1
2
3
4
messages = ["Hello Python world!","James","Kobe","Jordan"]
print('原列表:', messages)
messages.reverse()
print('reverse()后的列表:',messages)
1
2
原列表: ['Hello Python world!', 'James', 'Kobe', 'Jordan']
reverse()后的列表: ['Jordan', 'Kobe', 'James', 'Hello Python world!']

4.4.4 len()函数查询长度

任务一:使用len()查询列表长度

知识点:

描述:**len()**函数获得列表的长度

语法:len(object)

参数:集合或序列类型的对象。比如list,str

返回:长度值

属性:Python的build-in(内建)函数。所谓内建,就是Python自带的函数,类似于sorted()

在下面的示例中,列表包含4个元素,因此其长度为4:

1
2
cars =  ['bmw',  'audi',  'toyota',  'subaru']
print('长度:',len(cars))
1
2
mylist = "Hello"
print('长度:', len(mylist))
1
2
a = 1
len(a)

习题:

3-8 放眼世界:想出至少5个你渴望去旅游的地方

将这些地方存储在一个列表中,并确保其中的元素不是按字母顺序排列的

按原始排列顺序打印该列表。不要考虑输出是否整洁的问题,只管打印原始Python列表

使用**sorted()**按字母顺序打印这个列表,同时不要修改它

再次打印该列表,核实排列顺序未变

使用**sorted()**按与字母顺序相反的顺序打印这个列表,同时不要修改它

再次打印该列表,核实排列顺序未变

使用**reverse()**修改列表元素的排列顺序。打印该列表,核实排列顺序确实变了

使用**reverse()**再次修改列表元素的排列顺序。打印该列表,核实已恢复到原来的排列顺序

使用**sort()**修改该列表,使其元素按字母顺序排列。打印该列表,核实排列顺序确实变了

使用**sort()**修改该列表,使其元素按与字母顺序相反的顺序排列。打印该列表,核实排列顺序确实变了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
places =['Japan','America','Canada','Switzerland','Norway']
print(places)
print(sorted(places))
print(places)
print(sorted(places,reverse = True))
print(places)
places.reverse()
print(places)
places.reverse()
print(places)
places.sort()
print(places)
places.sort(reverse = True)
print(places)
1
2
3
4
5
6
7
8
9
['Japan', 'America', 'Canada', 'Switzerland', 'Norway']
['America', 'Canada', 'Japan', 'Norway', 'Switzerland']
['Japan', 'America', 'Canada', 'Switzerland', 'Norway']
['Switzerland', 'Norway', 'Japan', 'Canada', 'America']
['Japan', 'America', 'Canada', 'Switzerland', 'Norway']
['Norway', 'Switzerland', 'Canada', 'America', 'Japan']
['Japan', 'America', 'Canada', 'Switzerland', 'Norway']
['America', 'Canada', 'Japan', 'Norway', 'Switzerland']
['Switzerland', 'Norway', 'Japan', 'Canada', 'America']

3-9 晚餐嘉宾:在完成练习3-4~练习3-7时编写的程序之一中,使用**len()**打印一条消息,指出你邀请了多少位嘉宾来与你共进晚餐

1
2
3
4
5
6
7
customs = ['James','Kobe','Jordan']
customs[2] = 'ONeal'
print("I found a bigger table")
customs.insert(0 ,'Curry')
customs.insert(int(len(customs) / 2) ,'Garnett')
customs.append('Davis')
print(len(customs))
1
2
I found a bigger table
6

3-10 尝试使用各个函数:想想可存储到列表中的东西,如山岳、河流、国家、城市、语言或你喜欢的任何东西。编写一个程序,在其中创建一个包含这些元素的列表,然后,对于本章介绍的每个函数,都至少使用一次来处理这个列表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
customs = ['James','Kobe','Jordan']
customs[2] = 'ONeal'
customs.insert(0 ,'Curry')
customs.insert(int(len(customs) / 2) ,'Garnett')
customs.append('Davis')
print(len(customs))
print(sorted(customs))
customs.sort()
print(customs)
customs.reverse()
print(customs)
print(customs.pop())
customs.remove('Kobe')
print(customs)
del customs[:]
print(customs)
1
2
3
4
5
6
7
6
['Curry', 'Davis', 'Garnett', 'James', 'Kobe', 'ONeal']
['Curry', 'Davis', 'Garnett', 'James', 'Kobe', 'ONeal']
['ONeal', 'Kobe', 'James', 'Garnett', 'Davis', 'Curry']
Curry
['ONeal', 'James', 'Garnett', 'Davis']
[]

4.4.5 列表list常用操作

4.5 使用列表时避免索引错误

任务一:熟悉列表常见的索引错误

刚开始使用列表时,经常会遇到一种错误。假设你有一个包含三个元素的列表,想获得最后一个元素,误用索引为3:

1
2
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles[3])

Python试图向你提供位于索引3处的元素,但它搜索列表motorcycles时,却发现索引3处没有元素。鉴于列表索引差一的特征,这种错误很常见。有些人从1开始数,因此以为第三个元素的索引为3;但在Python中,第三个元素的索引为2,因为索引是从0开始的

知识点:

索引错误意味着Python无法理解你指定的索引

程序发生索引错误时,请尝试将你指定的索引减1,然后再次运行程序,看看结果是否正确

每当需要访问最后一个列表元素时,都可使用索引**-1**。对于列表长度发生变化的情形特别有效:

1
2
motorcycles = ['honda', 'yamaha', 'suzuki']
print(motorcycles[-1])

索引**-1总是返回最后一个列表元素,这里为值‘suzuki’**。仅当列表为空时,这种访问最后一个元素的方式才会导致错误:

1
2
3
motorcycles = []
print(motorcycles, len(motorcycles))
print(motorcycles[-1])

知识点:

找不到解决办法时,请尝试将列表或其长度打印出来

列表可能与想象中的截然不同,在程序对其进行了动态处理时尤其如此。通过查看列表或其包含的元素数,可帮助找出这种逻辑错误

习题:

3-11 有意引发错误:如果你还没有在程序中遇到过索引错误,就尝试引发一个这种错误。在你的一个程序中,修改其中的索引,以引发索引错误。关闭程序前,务必消除这个错误

1
2
names = ['James','Kobe','Jordan']
print(names[3])
1
2
3
4
5
6
7
---------------------------------------------------------------------------
IndexError Traceback (most recent call last)
<ipython-input-97-8e4ac68e70ad> in <module>
1 names = ['James','Kobe','Jordan']
----> 2 print(names[3])

IndexError: list index out of range

评论