首页 > Python笔记 阅读数:29

Python list列表用法详解

列表是 Python 中最常用的。它非常类似于 C、C++、Java 等语言中数组的概念。创建列表并不复杂,只要把不同的数据项用逗号(半角)分隔,并整体使用方括号[ ]起来即可。

如下面的代码所示:
In [1]: list1 = [ ]    #创建一个空列表list1
In [2]: type(list1)
Out[2]: list

不同于 C、C++、Java 中数组的地方是,Python 列表中各个数据项的类型并不需要都是相同的,我们可将其视为一个“大杂烩”数组。在数据处理上,有点类似于孔子说的“有教无类”。

访问列表中的元素非常便利,和访问数组元素类似,可以通过方括号和索引值访问对应的元素。类似于数组,列表中的每个元素都被分配了一个数字,即相对于列表起始位置的偏移(offset),也可称之为索引,索引的起始编号是 0。因此,正向索引时,第 1 个元素的索引是 0,第 2 个元素的索引是 1,以此类推。
In [3]: list1 = ['语文', "chemistry",  97, 20.1]     #创建一个列表变量 list1
In [4] : print(listl[0])                             #打印 list1 中索引值为 0 的元素
语文

除此之外,列表还支持反向索引:方括号内的偏移量为 -1,表示倒数第 1 个元素;偏移量为 -2,表示倒数第 2 个元素;以此类推。
In [5]: list1[-2]   #读取列表中倒数第 2 个元素
Out[5]: 97

列表的索引示意图如图 1 所示。

列表的索引示意图
图 1:列表的索引示意图

在 In [5] 处,我们使用了列表的负数索引值,这在 C、C++、Java 等语言中是绝对禁止的,因为这会产生数组越界,但在 Python 中却属稀松平常之举。对于正向索引,索引值与我们的日常编号错 1 位,如索引为 0 表示第 1 个元素,索引为 1 表示第 2 个元素,以此类推。反向索引不存在错位问题,-1 就表示倒数第 1 个元素,-2 表示倒数第 2 个元素,以此类推。

不同于字符串对象的不可变属性,列表内部元素的值是可变的(Mutable),也就是说列表元素的值是可以修改的,代码如下所示:
In [6]: list1[0] = "Chinese"    #修改 list1 中索引值为 0 的元素
In [7]: print(list1 [0])        #输出list1中索引值为 0 的元素,其值已经被修改
Chinese

鉴于列表的强大功能,也有人将其称为“打了激素的数组”。这么说也有道理,因为利用它还可以构建出“鱼龙混杂”的嵌套列表,如下所示:
In [8]: mix = [2, 'Chinese ', [1, 2, 3]]   #嵌套列表
In [9]: print(mix)                         #输岀列表
[2, 'Chinese', [1, 2, 3]]
In [10]: mix[2]                            #读取索引值为 2 的元素,即内部嵌套的列表
Out[10]: [1, 2, 3]

利用列表的索引(即下标),我们可以每次从列表中获取一个元素。但如果我们想一次获取多个元素,该怎么办呢?这也很容易解决。在 Python 中,可利用列表分片(slice)来实现这个需求,代码如下所示:
In [11]: list1 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] #创建一个包括 10 个元素的列表
In [12]: list1[0.5]                             #获取前5个元素
Out[12]: [0, 1, 2, 3, 4]

通过在列表中插入一个冒号:可以分割两个索引值,冒号左边的数值是索引起始值(如前面的 0 ),冒号右边的数值是索引结束值,但不包括该值(up to but not including),所以分片区间在严格意义上是“左闭右开”的,如上面代码的分片维度实际为 [0:5)。

需要说明的是,列表分片后并不会破坏原有的列表,而是根据语法规则建立了一个原有列表的部分副本。在分片操作之后,我们可在 IPython 中输入 print(list1) 来查看这个列表是否发生了变化。
In [13]: print(list1)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  #原有的列表,并没有发生任何变化 

事实上,以语法简单而称著的 Python,还提供了很多“语法糖”(Syntactic Sugar,即某些对语言功能没有影响但更方便程序员使用的语法)。例如,如果我们省略了冒号前面的数字,分片的索引起始值默认从 0 开始;如果省略冒号后边的数字,则表示分片以列表最后一个元素为终;如果两个边界都省略,只有一个冒号,表示从始到终输出所有元素。

代码如下所示:
In [14]: list1[:4]          #输出前4个元素
Out[14]: [0, 1, 2, 3]
In [15]: list1[4:]          #输出第4个元素以后的所有元素
Out[15]: [4, 5, 6, 7, 8, 9]
In [16]: list1[:]           #从开始到结尾,输出所有元素
Out[16]: [0, 1,2, 3, 4, 5, 6, 7, 8, 9]

实际上,分片操作还可以接收第三个参数,即步长(step)。如果我们使用步长参数,列表方括号中的冒号就变成两个。步长在默认情况下值为 1,有了这个默认值,在前面的代码中,方括号中可省略一个冒号。如果我们把步长改为其他值,这时方括号中的第二个冒号就不可以省略,代码如下所示:
In [17]: list1[0:9:2]     #步长为 2 ,每遍历 2 个元素取出 1 个
Out[17]: [0, 2’ 4, 6, 8]
In [18]: listl[::-1]      #列表分片从开始到结束,步长为 -1,相当于列表反转输出
Out[18]: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

列表的功能很强大,这一点还体现在它能实现“加法”与“乘法”操作上,这两种操作能分别完成列表的连接(Concatenate)和整体批量复制,代码如下所示:
In [19]: a = [1, 2, 3]     #定义列表 a
In [20]: b = [4, 5, 5]     #定义列表 b
In [21]: a + b             #将两个列表 a 和 b 连接
Out[21]: [1, 2, 3, 4, 5, 6]
In [22]: a * 3             #将列表 a 整体复制 3 遍,并连接为一个新的列表
Out [22]: [1, 2,3,1, 2,3, 1, 2, 3]

列表还可以和字符串配合使用,达到神奇的“炸开”效果,代码如下所示:
In [23]: list_ = list ("hello world") #将字符串转化为一个个字符列表
In [24]: list_                        #验证:形成单个字符列表
Out [24]: [ 'h', 'e' , '1','1' ,'o', ' ', 'w', 'o' , 'r', '1' , 'd' ]
除了上述基本操作,列表本身还封装了很多好用的方法,我们下节介绍。

相关文章