第3章 列表和元组

3.1问题:如何存取更多数据?

Python的列表、元组、字典等就是解决类似问题的有效方法。这些数据结构既可以存放单个数据,也可存放几十个、成千上万个数据,而且操作、维护里面的元素也非常方便。

3.2 列表概述

在Python中,一个列表中的数据类型可以相同,也可以各不相同。数据类型包括整数、实数、字符串等基本类型,也包括列表、元组、字典、集合以及其他自定义类型的对象,可以说包罗万象。

3.3 如何访问列表元素

列表是有序的,列表中每个元素都有唯一标号(即对应的索引),不过要要注意一点,索引是以0开始的,这或许与很多度量工具的起始值一致,米尺也是从0开始的。不过列表的索引除了可以从左到右标识,也可以从右到左标识,此时,索引就为负数。列表中各元素与对应索引的关系,可参考图3-1。图3-1 列表a的索引从左到右算起,第一个索引为0,第二个为1,依次类推。

图3-1 列表a中元素与正索引的对应关系
对列表a的元素,也可以从右到左算起,最右这个元素的索引是-1(注意不是0,否则,将与从左到右的第一个索引冲突!),依次类推,具体可参考图3-2。

图3-2 列表a中元素与负索引的对应关系
了解了列表中元素与对应索引的关系,获取列表中的元素就非常简单了。

3.3.1 获取一个元素

从列表中,提取单个元素,直接指定对应索引即可,示例如下:

3.3.2 获取连续多个元素

一次从列表中提取多个连续元素,可以采用冒号,具体示例如下:

打印结果
[2, 3, 4]
[4, 2, 6]
[4, 2, 6, 7]

3.3.3 遍历列表

以上介绍了如何查看列表的部分元素,如果需要遍历所有元素或同时获取列表的元素及对应索引,该如何处理呢?这样的场景,在数据分析、数据处理中经常会遇到。要遍历所有元素,可以使用for循环(for循环第4章将介绍),同时查看列表的索引和对应元素,可以使用enumerate()函数。以下是实现遍历列表的具体代码:

北京|上海|广州|深圳|
====遍历索引及对应元素====
0 北京
1 上海
2 广州
3 深圳

3.3.4 访问列表经常出现的一个问题

我们在访问列表经常遇到list index out of range这个问题,出现这个问题,主要是访问的索引超出列表范围,比如,访问一个只有4个元素的列表,但索引却大于4;访问一个空列表也会报这个错误,具体可参考如下代码:

为有效避免这类问题,可以用len函数得到列表的元素个数n,然后用索引小于n去访问列表。

3.4 对列表进行增、删、改

列表是序列,而且是可以修改的序列,列表对象自身带有很多操作函数,使用这些函数就可对列表进行增加、删除、修改等操作。

3.4.1 添加新元素到列表

往列表中添加新元素方法很多,如以追加的方式加入、以插入的方式加入、还可以拼接两个列表的加入等等。对应的列表函数有append、insert、extend等,具体请参考表3-1。
表3-1 添加元素的列表函数

列表函数 返回值
lst.append(x) 在列表lst末尾添加元素x
lst.insert(i, x) 将元素x插入到索引为i指定的位置,相当于lst[i]=x
lst.extend(lst2) 将列表lst2的所有元素追加到列表lst末尾

以下是往列表添加新元素的示例代码。

['Python', 'Java', 'C++', 'keras']
['Python', 'Java', 'C++', 'Pytorch', 'keras']
['Python', 'Java', 'C++', 'Pytorch', 'keras', 'TensorFlow', 'Caffe2']

3.4.2 从列表中删除元素

删除列表中的元素,你可以根据位置或值来删除列表的元素。
(1)创建列表
先用for循环及append创建一个列表lst4,具体步骤是先创建一个空列表,然后,用for循环从一个已知列表中获取元素i,把i*2+1放入列表lst4中。

(2)根据位置删除列表元素
如果知道要删除的元素索引或位置,你可以使用del、pop(i)、pop()方法。

打印结果
[3, 5, 7, 3, 9, 11]
[3, 7, 3, 9, 11]
[3, 3, 9, 11]
7
[3, 3, 9]
(3)根据值删除元素
有时要删除明确值,对位置或其索引不关心,这种情况下,可以用remove(x)函数。
接下来我们从lst4= [3, 3, 9]删除3,这个列表中有两个3,remove(x)只会删除第一个匹配的值。
如果要删除列表指定值,该值有多次重复,那么就需要使用循环语句。第4章我们将介绍类似场景的实例。

3.4.3 修改列表中的元素

修改列表中元素,可以先通过索引定位该元素,然后再给赋值。

['欲穷千里目', '更上一层楼', '王之涣']

3.5 统计分析列表

如果列表中元素都是数字,统计分析列表的元素,Python提供很多内置函数,如求最大(小)值、统计某个值的总数、列表各元素之和、获取某个值的索引等。

3.5.1 求列表最大(小)值

统计列表最大(小)值,使用内置函数max或min即可。

3.5.2 求列表总和或平均值

利用sum内置函数求列表总和,再除以元素个数便可得到平均值。

3.5.3 求列表元素出现次数及对应索引

3.5.4 求列表元素总数

用内置函数len可以得到列表元素个数,注意,列表的元素可以是字符串、数字、列表、字典、元组等。如果列表中还有列表,或其它对象,通过len得到的元素个数是如何统计的呢?这个问题很重要,以后与多维数据打交道时,经常会遇到类似问题。接下来还是以实例来说吧。

3.6 组织列表

对列表各元素进行排序是经常遇到的问题,Python提供了几种方法:永久修改列表排序,使用列表函数sort(),使用这种方法不保留底稿;使用内置函数sorted()临时修改列表排序,原列表的次序不变;把列表颠倒过来,使用reverse()函数。

3.6.1 使用sort()函数

sort()将永久修改列表的排序,如要恢复列表原来的次序就不方便。

3.6.2 使用sorted()函数

内置函数sorted()只是临时改变列表的次序,原列表次序不变。

3.6.3 使用reverse()函数

reverse()函数与排序函数不同,只是把列表的排列次数倒过来。

列表函数reverse()也是永久修改列表次数,不过只要再次使用该函数就可复原列表。

3.7 生成列表

前面介绍的列表基本都是手工创建的,用这种方法如果元素不多还可接受,如果要生成几百个、上万个元素就不方便了。这里我们介绍几种生成列表的简单方法,使用这些方法,你可以生成任意多的整数、小数都很方便。

3.7.1range()函数

内置函数range()可以自动生成数据,如果再结合for循环,几乎可以生成任何数据集。range()函数的格式为:
range ([start], stop[, step])
range的功能就是生成整数序列,共有3个参数,其中start,step参数是可选的。start表示序列的初始值,缺省为0。参数step表示步长,为整数,缺省值为1。stop为序列的上限,序列元素不包括该值,range()函数的参数具体含义,可参考图3-3。

图3-3 range函数示例
在图3-3 中,range(5),只使用了一个stop参数,stop=5,但生成的序列不包括5。参数start、step都取缺省值,分别为0,1。range函数各种情况的具体使用,请看如下代码。

3.7.2用range()创建列表

用range()函数创建列表非常方便,除了使用for循环,还可以用list()函数,直接把range结果转换为列表。
(1)使用range函数及for循环生成列表

(2)使用range()及list()函数生成列表

3.8 元组

前面我们介绍了列表,列表是可修改的序列,其应用比较广泛。有时,我们又希望生成后的列表不能修改,只能读,就像一些只能读的文件一样,用元组就可满足这需求,元组就是不可修改的序列。

3.8.1 定义元组

定义列表用方括号[],定义元组用圆括号()。定义元组后,就可以使用索引访问元素,这个与列表类似。

由此可知,定义只有一个元素的元组时,不能简单把该元素加圆括号,否则,把一个数字用圆括号括起只是一个数字,而不是元组。
那一个元素的元组如何定义呢?在元素后加上一个逗号即可,如:

3.8.2 查看元组中元素

查看元组中的元素,与查看列表中元素一样,通过索引就可。

3.8.3 使用tuple()生成元组

用list()函数可以把range生成的序列转换为列表,与此类似可以用tuple()函数把range生成的序列转换为元组,也可用tuple()函数把列表转换为元组。

3.9练习

(1)生成一个至少含5个元素的列表,打印各元素的和。
(2)把(1)中得到的列表中倒序,即如果由(1)得到的列表为[3,4,5,8,2],其倒序为[2,8,5,4,3]。
(3)使用range函数,求1到1000的连续自然数的平方和。