这一节,我们来讨论Python中数组类型:list
。不过,我们的重点并不是一一过一遍每一个API的用法,这并没有太多意义。如果大家有过一些开发经验,理解这些API并没有什么困难。
我们要做的,仅仅是快速让大家熟悉list
在Python中的表达方式,以及Python特有的地方。剩下的工作,就可以在实际的开发中,用到哪学到哪了。
创建List
先来看如何创建list
,和强类型语言不同,我们无须指定数组中存储的具体数据类型,例如:
- 定义空
list
的时候,无须指定list
中元素的类型:
list1 = []
list2 = list()
- 同一个
list
中既可以存储相同类型的值,也可以存储不同类型的值:
numList = [8, 6, 5, 7, 2]
mixList = [1, "one", 1.0]
- 甚至,我们可以把类型和元素个数都不同的两个
list
添加到list
中:
nestedList = [numList, mixList]
这样,就定义了一个嵌套的list
对象。
List常用操作
接下来,我们看一些list
的常用操作。
合并Lists
首先,是合并多个list
,我们有两种不同的方式。第一种,和字符串的合并是类似的,直接把要合并的list
对象相加就好了:
print(mixList + numList)
# [1, 'one', 1.0, 8, 6, 5, 7, 2]
第二种,是直接修改对象本身,在其尾部追加一个list
:
print(mixList.extend(numList))
# None
print(mixList)
# [1, 'one', 1.0, 8, 6, 5, 7, 2]
从上面的注释中可以看到,extend
的返回值是None
,它只会把numList
中的值,直接添加到mixList
尾部。因此,当我们再查看mixList
的时候,就可以看到追加的结果了。
extend和append方法的区别
实际上,除了extend
之外,我们还有一种给list
追加元素的方法,叫append
,和extend
不同的是,无论我们传递给它什么,它都会直接插在list
末尾,无论是单个元素,还是另外一个list
。例如:
numList.append(9)
print(numList)
# [8, 6, 5, 7, 2, 9]
从注释就可以看到,append
直接把数字9添加到了numList
末尾。或者,我们也可以像下面这样直接塞一个list
:
numList.append([9, 10])
print(numList)
# [8, 6, 5, 7, 2, [9, 10]]
这时,就会看到numList
的最后一个元素,就是一个list
对象,append
会把它的参数当作一个整体,添加到numList
末尾。
看到这里,你可能会想一个问题,该如何在extend
和append
之间选择呢?其实,从它们各自的行为,我们就已经有了实践的标准:
-
append
是O(1)算法,当我们要把list
作为一个整体添加到list
中时,使用append
是更快的做法,不要遍历list
之后,反复调用append
插入单个元素; -
extend
是O(n)算法,但是它是通过C实现的,当要把一个list
中的元素逐个添加到另外一个list
中时,总是应该选择extend
,无论是写起来还是执行起来,它的效率都比append
版本高很多;
排序list中的元素
其次,是对list
中的所有元素排序。这个方法和extend
一样,也没有返回值,而是直接在原对象上生效的:
numList = [8, 6, 5, 7, 2]
numList.sort()
print(numList)
# [2, 5, 6, 7, 8]
这里,多说一句,list
作为一个类对象,是个引用类型,因此,要想保留sort
,extend
或append
之前的值,单纯的把它赋值给另一个变量是不行的:
numList1 = numList
numList.sort()
print(numList)
print(numList1)
在调用sort
之后,numList
和numList1
的值都会变成[2, 5, 6, 7, 8]
。这里,我们必须使用deep copy的做法,明确调用list
的copy
方法:
numList1 = numList.copy()
这样,对numList
的操作就不会影响到numList1
了。
访问list中的元素
第三,是访问数组中的元素,和字符串相同,list
也支持单索引和range索引访问:
print(numList[0]) # 2
print(numList[0:3]) # [2, 5, 6]
并且,在Python中,range也可以是负数,-1表示list
的最后一个元素,-2表示倒数第二个,以此类推。因此,对numList[0:3]
来说,也可以这样:
print(numList[0:-2]) # [2, 5, 6]
插入元素
第四,是在list
的特定位置,插入元素,为此,使用insert
方法就好,显而易见,这也是个直接对原对象生效的方法:
numList.insert(1, 9)
print(numList)
# [8, 9, 6, 5, 7, 2]
insert
的第一个参数是要插入的位置,第二个参数是要插入的值。要说明一点的是,如果你使用的位置超过了list
的最大长度,insert
就会把元素插在list
末尾。例如:
numList.insert(100, 9)
print(numList)
# [8, 6, 5, 7, 2,9]
删除元素 - 理解del和pop的差异
第五,来看如何从list
中删除元素,常用的方法有三种:
第一种,是使用pop
方法,它删除并返回指定位置的元素,如果位置超出list
范围会发生运行时错误:
numList = [8, 9, 6, 5, 7, 2]
print(numList.pop(0))
# 8
print(numList)
# [9, 6, 5, 7, 2]
第二种,是使用remove
方法,它直接删除list
中第一个和参数值相等的元素,并且,没有返回值。如果list
中不存在要删除的元素,会导致运行时错误:
numList = [8, 6, 5, 7, 2]
print(numList.remove(2))
print(numList)
# [8, 6, 5, 7]
第三种,是使用全局的del
函数,我们直接来看代码:
numList = [8, 6, 5, 7, 2]
del(numList[0:5:2])
print(numList)
# [6, 7]
这里,传给del
方法的,是一个list
的切片,它既可以是形如numList[0]
这样的单个元素,也可以是numList[0:5]
这样的range,还可以是指定步进值的range numList[0:5:2]
。
在我们的例子里,表示从位置0开始,每两个元素删掉一个,一直到位置5。因此,执行之后,结果就是[6, 7]
了。
常用的其它方法
最后,是一些常用的辅助方法:例如,获取数组元素个数,这个用法带有浓浓的C的味道,我们要使用全局len
函数:
print(len(numList)) # 5
要查询某个元素是否在list
里,可以使用index
方法,它会返回元素在数组中的位置。要注意的是,如果查询的元素不存在,会发生运行时错误。但现在不用在意这个问题,稍后,我们会专门提到错误处理方法:
print(numList.index(2)) # 0
网友评论