简要介绍
列表是三种主要的线性集合中的一种(另两种是栈和队列)。列表所支持的操作,比栈和队列还要广泛,因此其应用也更广,并且也更难实现。尽管Python包含了一个内建的列表操作,但是还有几种可能的实现。为了让列表的大量操作更有意义,我们可以将其分为3类:基于索引的操作、基于内容的操作、基于位置的操作。
注意:尽管列表中的项在逻辑上总是连续的,但是它们在物理内存中不一定是连续的。列表的数组实现了使用物理位置来表示逻辑顺序,但是链表的实现并没有那么做。
列表的操作分类
基于索引的操作
基于索引的操作会操作列表中的指定索引的项,在基于数组实现的例子中,这些操作也提供了方便的随机访问。
列表方法 | 作用 |
---|---|
L.insert(i,item) | 在将各项向右移动一个位置之后,在索引i添加项item |
L.pop(i = None) | 删除并返回位于索引i的项,如果没有参数i,删除并返回最后一项;先验条件:0 <= i <= len(L) |
L.[i] | 返回位于索引i的项,先验条件:0 <= i <= len(L) |
L.[i] = item | 用item替代位于索引i的项,先验条件:0 <= i <= len(L) |
从这个视角来查看的时候,列表有时候叫做向量或序列,并且由于它们使用索引,会令人想起数组。然而,数组是一种具体的数据结构,拥有基于单个的物理内存块的一种特定的、不变的实现,而列表是一种数据类型,可以以各种方式表示,其中只有一种方式使用了数组。此外,列表所拥有的基本操作的范围,要比数组的大得多,即使合适的数组序列可以模拟所有的列表操作。
基于内容的操作
列表方法 | 作用 |
---|---|
L.add(item) | 在列表的尾部添加一项 |
L.remove(item) | 从列表中删除一项。先验条件:该项位于列表之中 |
L.index(item) | 返回列表中的第一个实例的位置。先验条件:该项位于列表之中。 |
基于位置的操作
基于位置的操作是相对于当前建立的名为游标的位置而执行的。这个操作允许程序员通过移动游标在列表中导航。尽管在Python中列表已经支持迭代器了,它允许程序员使用for循环来访问列表的项,但列表迭代器要更为强大一些。与简单的迭代器不同,列表迭代器支持移动到之前的位置,直接移动到第一个位置以及直接移动到最后一个位置。除了这些导航操作以后,列表迭代器还支持从游标位置插入、替代和删除项。
这里,我们可以通过在列表上运行listIterator方法(列表类ArrayList中含有一个listIterator方法,这个方法调用了列表迭代器类ArrayListIterator)来创建列表迭代器,如下所示:
listIterator = aList.listIterator()
一开始,在列表迭代器第一次实例化的时候,其游标是未定义的。在将项插入到列表中之后,用户可以通过将游标移动到列表的开始或末尾,从而建立游标的位置。从这些位置开始,用户可以以某种方式导航到另一个位置。
操作 | 目标 |
---|---|
LI.hasNext() | 如果在游标之后有项,返回True;如果游标未定义或位于最后一项之后,返回False |
LI.next() | 返回下一项并且将游标向右移动一个位置。先验条件:hasNext返回True,在最近一次next或previous操作之后,列表上没有干扰性修改 |
LI.hasPrevious() | 如果在游标之前有项,返回True;如果游标未定义或位于第一项之前,返回False |
LI.previous() | 返回之前的一项,并且将游标向右移动一个位置。先验条件:hasPrevious返回True,在最近一次next或previous操作之后,列表上没有干扰性修改 |
LI.first() | 将游标移动到第一项之前(如果有第一项的话) |
LI.last() | 将游标移动到最后一项之后(如果有最后一项的话) |
操作 | 作用 |
---|---|
LI.insert(item) | 如果定义了游标的话,在其后插入项;否则,在列表的尾部插入项 |
LI.remove() | 删除最近的next或previous操作所返回的项。先验条件:在最近一次next或previous之后,列表上没有干扰性修改 |
LI.replace(item) | 替代最近一次next或previous操作调用所返回的项。先验条件:在最近一次next或previous之后,列表上没有干扰性修改 |
下表列出了在列表迭代器上的一系列操作:
操作 | 操作之后的位置 | 操作后的列表 | 返回值 | 说明 |
---|---|---|---|---|
实例化 | 未定义 | 空 | 一个新的列表迭代器 | |
insert(a) | 未定义 | a | 当游标未定义的时候,插入的每一项都位于列表的末尾 | |