列表和元组)
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了列表和元组)相关的知识,希望对你有一定的参考价值。
本文内容全部出自《Python基础教程》第二版,在此分享自己的学习之路。
______欢迎转载:http://www.cnblogs.com/Marlowes/p/5293195.html______
Created on Xu Hoo
本章将引入一个新的概念:数据结构。数据结构是通过某种方式(例如对元素进行编号)组织在一起的数据元素的集合,这些数据元素可以是数字或者字符,甚至可以是其他数据结构。在Python中,最基本的数据结构是序列(sequence),序列中的每个元素被分配一个序号——即元素的位置,也称为索引。第一个索引是0,第二个则是1,以此类推。
注:日常生活中,对某些东西计数或者编号的时候,可能会从1开始。所以Python使用的编号机制可能看起来很奇怪,但这种方法其实非常自然。在后面的章节中可以看到,这样做的一个原因是也可以从最后一个元素开始计数;序列中的最后一个元素标记为-1,倒数第二个元素为-2,以此类推。这就意味着我们可以从第一个元素向前或向后计数了,第一个元素位于最开始,索引为0.使用一段时间后,读者就会习惯于这种计数方式了。
本章首先对序列作一个概览,接下来讲解对所有序列(包括元组和列表)都通用的操作。这些操作也同样适用于字符串。尽管下一章才会全面介绍有关字符串操作的内容,但是本章的一些例子已经用到了字符串操作。
在完成了基本介绍后,会开始学习如何使用列表,同时看看它有什么特别之处。然后讨论元组。元组除了不能更改之外,其他的性质和列表都很类似。
2.1 序列概述
Python包含6中內建的序列,本章重点讨论最常用的两种类型:列表和元组。其他的內建序列类型有字符串(将在下一章再次讨论)、Unicode字符串、buffer对象和xrange对象。
列表和元组的主要却别在于:列表可以修改,元组则不能。也就是说如果要根据要求来添加元素,那么列表可能会更好用;而处于某些原因,序列不能修改的时候,使用元组则更为合适。使用后者通常是技术性的,它与Python内部的运作方式有关。这也是內建函数会返回元组的原因。一般来说,在自己编写的程序中,几乎在所有的情况下都可以用列表代替元组(第四章将会介绍一个需要注意的例外情况:使用元组作为字典的键。在这种情况下,因为键不可更改,所以就不能使用列表)。
在需要操作一组数值的时候,序列很好用。可以用序列表示数据库中一个人的信息——第1个元素是姓名,第2个元素是年龄。根据上述内容编写一个列表(列表的各个元素通过逗号分隔,写在方括号中),如下所示:
>>> info = ["XuHoo", 19]
同时,序列也可以包含其他的序列,因此,构建如下的一个人员信息的列表也是可以的,这个列表就是你的数据库:
>>> user_1 = ["XuHoo", 19] >>> user_2 = ["Marlowes", 19] >>> database = [user_1, user_2] >>> database [[‘XuHoo‘, 19], [‘Marlowes‘, 19]]
注:Python之中还有一种名为容器(container)的数据结构。容器基本上是包含到其他对象的任意对象。序列(例如列表和元组)和映射(例如字典)是两类主要的容器。序列中的每个元素都有自己的编号,而映射中的每个元素则有一个名字(也称为键)。在第四章会介绍更多有关映射的知识。至于既不是序列也不是映射的容器类型,集合(set)就是一个例子,请参见第十章的相关内容。
2.2 通用序列操作
所有序列类型都可以进行某些特定的操作。这些操作包括:索引(indexing)、分片(slicing)、加(adding)、乘(multiplying)以及检查某个元素是否属于序列的成员(成员资格)。除此之外,Python还有计算序列长度、找出最大元素和最小元素的內建函数。
注:本节有一个重要的操作没有提到——迭代(iteration)。对序列进行迭代的意思是:依次对序列中的每个元素重复执行某些操作。更多信息请参见5.5节。
2.2.1 索引
序列中的所有元素都是有编号的——从0开始递增。这些元素可以通过编号分别访问,如下例所示:
>>> greeting = "Hello" >>> greeting[0] ‘H‘
注:字符串就是一个由字符组成的序列。索引0指向第1个元素,在这个例子中就是字母H。
这就是索引。可以通过索引获取元素。所有序列都可以通过这种方式进行索引。使用负数索引时,Python会从右边,也就是从最后1个元素开始计数。最后1个元素的位置编号是-1(不是-0,因为那会和第1个元素重合):
>>> greeting[-1] ‘o‘
字符串字面值(就此而言,其他序列字面量亦可)能够直接使用索引,而不需要一个变量引用它们。两种做法的效果是一样的:
>>> "Hello"[-1] # String ‘o‘ >>> ["H", "e", "l", "l", "o"][-1] # List ‘o‘
如果一个函数调用返回一个序列,那么可以直接对返回结果进行索引操作。例如,假设你只对用户输入年份的第四个数字感兴趣,那么,可以进行如下操作:
>>> fourth = raw_input("Year: ")[3] Year: 1997 >>> fourth ‘7‘
代码清单2-1是一个示例程序,它要求输入年、月(1~12的数字)、日(1~31),然后打印出相应日期的月份名称,等等。
1 #!/usr/bin/env python 2 # coding=utf-8 3 4 # 根据给定的年月日,以数字形式打印出日期 5 months = [ 6 "January", 7 "February", 8 "March", 9 "April", 10 "May", 11 "June", 12 "July", 13 "August", 14 "September", 15 "October", 16 "November", 17 "December" 18 ] 19 20 # 以1~31的数字作为结尾的列表 21 endings = ["st", "nd", "rd"] + 17 * ["th"] 22 + ["st", "nd", "rd"] + 7 * ["th"] 23 + ["st"] 24 25 year = raw_input("Year: ") 26 month = raw_input("Month(1~12): ") 27 day = raw_input("Day(1~31): ") 28 29 month_number = int(month) 30 day_number = int(day) 31 32 # 记得要将月份和天数减1,以获得正确的索引 33 month_name = months[month_number - 1] 34 ordinal = day + endings[day_number - 1] 35 36 print month_name + " " + ordinal + ", " + year
以下是程序执行的一部分结果:
Year: 1997 Month(1~12): 9 Day(1~31): 10 September 10th, 1997
2.2.2 分片
与使用索引来访问单个元素类似,可以使用分片操作来访问一定范围内的元素。分片通过冒号隔开的两个索引来实现:
>>> tag = ‘<a href="http://www.python.org">Python web site</a>‘ >>> tag[9:30] ‘http://www.python.org‘ >>> tag[32:-4] ‘Python web site‘
分片操作对于提取序列的一部分是很用的。而编号在这里显得尤为重要。第1个索引是要提取的第1个元素的编号,而最后的索引则是分片之后剩余部分的第1个元素的编号。
>>> numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> numbers[3:6] [4, 5, 6] >>> numbers[0:1] [1]
简而言之,分片操作的实现需要提供两个索引作为边界,第1个索引的元素是包含在分片内的,而第2个则不包含在分片内。
1.优雅的捷径
假设需要访问最后3个元素(根据先前的例子),那么当然可以进行显示的操作:
>>> numbers[7:10]
[8, 9, 10]
现在,索引10指向的是第11个元素——这个元素并不存在,却是在最后一个元素之后(为了让分片部分能够包含列表的最后一个元素,必须提供最后一个元素的下一个元素所对应的索引作为边界)。明白了吗?
现在,这样的做法是可行的。但是,如果需要从列表的结尾开始计数呢?
>>> numbers[-3:-1]
[8, 9]
看来并不能以这种方式访问最后的元素。那么使用索引0作为最后一步的下一步操作所使用的元素,结果又会怎么样呢?
>>> numbers[-3:0]
[]
这并不是我们所要的结果。实际上,只要分片中最左边的索引比它右边的晚出现在序列中(在这个例子中是倒数第3个比第1个晚出现),结果就是一个空的序列。幸好,可以使用一个捷径:如果分片所得部分包括序列结尾的元素,那么,只需置空最后一个索引即可。
>>> numbers[-3:]
[8, 9, 10]
这种方法同样适用于序列开始的元素:
>>> numbers[:3]
[1, 2, 3]
实际上,如果需要复制整个序列,可以将两个索引都置空:
>>> numbers[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
代码清单2-2是一个小程序,它会提示输入URL(假设它的形式为http://www.somedomainname.com),然后提取域名。
1 #!/usr/bin/env python 2 # coding=utf-8 3 4 # 对http://www.something.com形式的URL进行分割 5 6 url = raw_input("Please enter the URL: ") 7 domain = url[11:-4] 8 9 print "Domain name: " + domain
以下是程序运行的示例:
Please enter the URL: http://www.python.org
Domain name: python
2.更大的步长
进行分片的时候,分片的开始和结束点需要进行指定(不管是直接还是间接)。而另外一个参数(在Python2.3加入到内建类型)——步长(step length)——通常都是隐式设置的。在普通的分片中,步长是1——分片操作就是按照这个步长逐个遍历序列的元素,然后返回开始和结束点之间的所有元素。
>>> numbers[0:10:1]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
在这个例子中,分片包含了另外一个数字。没错,这就是步长的显示设置。如果步长被设置为比1大的数,那么就会跳过某些元素。例如,步长设为2的分片包括的是从头开始到结束每隔1个的元素。
>>> numbers[0:10:2] [1, 3, 5, 7, 9] >>> numbers[3:6:3] [4]
之前提及的捷径也可以使用。如果需要将每4个元素中的第1个提取出来,那么只要将步长设置为4即可:
>>> numbers[::4]
[1, 5, 9]
当然,步长不能为0(那不会执行),但步长可以是负数,此时分片从右到左提取元素:
>>> numbers[8:3:-1] [9, 8, 7, 6, 5]
>>> numbers[10:0:-2]
[10, 8, 6, 4, 2]
>>> numbers[0:10:-2]
[]
>>> numbers[::-2]
[10, 8, 6, 4, 2]
>>> numbers[5::-2]
[6, 4, 2]
>>> numbers[:5:-2]
[10, 8]
在这里要得到正确的分片结果需要动些脑筋。开始点的元素(最左边的元素)包括在结果之中,而结束点的元素(最右边的元素)则不在分片之内。当使用一个负数作为步长时,必须让开始点(开始索引)大于结束点。在没有明确指定开始点和结束点的时候,正负数的使用可能会带来一些混淆。不过在这种情况下Python会进行正确的操作:对于一个正数步长,Python会从序列的头部开始向右提取元素,直到最后一个元素;而对于负数步长,则是从序列的尾部开始向左提取元素,直到第一个元素。
2.2.3 序列相加
通过使用加运算符可以进行序列的连接操作:
>>> [1, 2, 3] + [4, 5, 6] [1, 2, 3, 4, 5, 6] >>> "Hello, " + "world!" ‘Hello, world!‘ >>> [1, 2, 3] + "wrold!" Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate list (not "str") to list
正如错误信息所提示的,列表和字符串是无法连接在一起的,尽管它们都是序列。简单来说,两种相同类型的序列才能进行连接操作。
2.2.4 乘法
用数字x乘以一个序列会生成新的序列,而在新的序列中,原来的序列将被重复x次。
>>> "Python" * 5 ‘PythonPythonPythonPythonPython‘ >>> [19] * 10 [19, 19, 19, 19, 19, 19, 19, 19, 19, 19]
None、空列表和初始化
空列表可以简单地通过两个中括号进行表示([])——里面什么东西都没有。但是,如果想创建一个占用十个元素空间,却不包括任何有用内容的列表,又该怎么办呢?可以像前面那样使用[19]*10,或者使用[0]*10,这会更加实际一些。这样就生成了一个包括10个0的列表。然而,有时候可能会需要一个值来代表空值——意味着没有在里面放置任何元素。这个时候就需要使用None。None是一个Python的内建值,它的确切含义是“这里什么也没有”。因此,如果想初始化一个长度为10的列表,可以按照下面的例子来实现:
>>> sequence = [None] * 10
>>> sequence
[None, None, None, None, None, None, None, None, None, None]
代码清单2-3的程序会在屏幕上打印一个由字符组成的“盒子”,而这个“盒子”在屏幕上居中而且能根据用户输入的句子自动调整大小。
代码可能看起来很复杂,但只使用基本的算法——计算出有多少个空格、破折号等字符,然后将它们放置到合适的位置即可。
1 #!/usr/bin/env python 2 # coding=utf-8 3 4 # 以正确的宽度在居中的“盒子”内打印一个句子 5 6 # 注意,整数除法运算符(//)只能用在Python2.2以及后续的版本,在之前的版本中,只能使用普通除法(/) 7 8 sentence = raw_input("Sentence: ") 9 10 screen_width = 80 11 text_width = len(sentence) 12 box_width = text_width + 6 13 left_margin = (screen_width - box_width) // 2 14 15 print 16 print " " * left_margin + "+" + "-" * (box_width - 2) + "+" 17 print " " * left_margin + "| " + " " * text_width + " |" 18 print " " * left_margin + "| " + sentence + " |" 19 print " " * left_margin + "| " + " " * text_width + " |" 20 print " " * left_margin + "+" + "-" * (box_width - 2) + "+" 21 print
下面是该例子的运行情况:
Sentence: He‘s a very naughty boy! +----------------------------+ | | | He‘s a very naughty boy! | | | +----------------------------+
2.2.5 成员资格
为了检查一个值是否在序列中,可以使用in运算符。该运算符和之前已经讨论过的(例如+、*运算符)有一点不同。这个运算符检查某个条件是否为真,然后返回相应的值:条件为真返回True,条件为假返回False。这样的运算符叫做布尔运算符,而返回的值叫做布尔值。第五章的条件语句部分会介绍更多关于布尔表达式的内容。
以下是一些使用了in运算符的例子:
>>> permissions = "rw" >>> "w" in permissions True >>> "x" in permissions False >>> users = ["mlh", "foo", "bar"] >>> raw_input("Please enter your user name: ") in users # 用户名存在 Please enter your user name: mlh True >>> raw_input("Please enter your user name: ") in users # 用户名不存在 Please enter your user name: Marlowes False >>> subject = "$$$ Get rich now!!! $$$" >>> "$$$" in subject True
最初的两个例子使用了成员资格测试分别来检查"w"和"x"是否出现在字符串permissions中。在UNIX系统中,这两行代码可以作为查看文件可写和可执行权限的脚本。接下来的例子则是检查所提供的用户名是否存在用户列表中。如果程序需要执行某些安全策略,那么这个检查就派上用场了(在这种情况下,可能还需要使用密码)。最后一个例子可以作为垃圾邮件过滤器的一部分,它可以检查字符串subject是否包含字符串"$$$"。
注:最后一个检查字符串是否包含"$$$"的例子有些不同。一般来说,in运算符会检查每一个对象是否为某个序列(或者是其他数据集合)的成员(也就是元素)。然后,字符串唯一的成员或者元素就是它的字符。下面的例子就说明了这一点:
>>> "P" in "Python" True
实际上,在早期的Python版本中,以上代码是唯一能用于字符串成员资格检查的方法——也就是检查某个字符是否存在于一个字符串中。如果尝试去检查更长的子字符串(例如"$$$"),那么会得到一个错误信息(这个操作会引发TypeError,即类型错误)。为了实现这个功能,我们必须使用相关的字符串方法。第三章会介绍更多相关的内容。但是从Python2.3起,in运算符也能实现这个功能了。
代码清单2-4给出了一个查看用户输入的用户名和PIN码是否存在于数据库(实际上是一个列表)中的程序。如果用户名/PIN码这一数值对存在于数据库中,那么就在屏幕上打印“Access granted”(第一章已经提到过if语句,第五章还将对其进行全面讲解)。
1 #!/usr/bin/env python 2 3 # 检查用户名和PIN码 4 5 database = [ 6 ["albert", "123"], 7 ["dilbert", "3521"], 8 ["smith", "6542"], 9 ["jones", "5634"] 10 ] 11 12 username = raw_input("Please enter your username: ") 13 pin = raw_input("Please enter your PIN: ") 14 15 if [username, pin] in database: 16 print "Access granted"
2.2.6 长度、最小值和最大值
内建函数len、min和max非常有用。len函数返回序列中所包含元素的数量,min函数和max函数则分别返回序列中最大和最小元素(在第五章的“比较运算符”部分会更加详细介绍对象比较的内容)。
>>> numbers = [100, 34, 678] >>> len(numbers) 3 >>> max(numbers) 678 >>> min(numbers) 34 >>> max(2, 3) 3 >>> min(9, 3, 2, 5) 2
根据上述解释,我们可以很容易地理解例子中的各个操作是如何实现的,除了最后两个表达式可能会让人有些迷惑。在这里,max函数和min函数的参数并不是一个序列,而是以多个数字直接作为参数。
2.3 列表:Python的“苦力”
在前面的例子中已经用了很多次列表,它的强大之处不言而喻。本节会讨论列表不同于元组和字符串的地方:列表是可变的——可以改变列表的内容,并且列表有很多有用的、专门的方法。
2.3.1 list函数
因为字符串不能像列表一样被修改,所以有时根据字符串创建列表会很有用。list函数(它实际上是一种类型而不是函数,但在这里两者的区别并不重要)可以实现这个操作:
>>> list("Hello") [‘H‘, ‘e‘, ‘l‘, ‘l‘, ‘o‘]
注意,list函数适用于所有类型的序列,而不只是字符串。
注:可以用下面的表达式将一个由字符(如前面代码中的)组成的列表转换为字符串:
‘‘.join(somelist)
在这里,somelist是需要转换的列表。要了解这行代码真正的含义,请参考第三章有关join函数的部分。
2.3.2 基本的列表操作
列表可以使用所有适用于序列的标准操作,例如索引、分片、连接和乘法。有趣的是,列表是可以修改的。本节会介绍一些可以改变列表的方法:元素赋值、元素删除、分片赋值以及列表方法(请注意,并不是所有的列表方法都能真正地改变列表)。
1.改变列表:元素赋值
改变列表是很容易的,只需要使用第一章提到的普通赋值语句即可。然而,我们并不会使用x=2这样的语句进行赋值,而是使用索引标记来为某个特定的、位置明确的元素赋值。如x[1]=2。
>>> x = [1, 1, 1] >>> x[1] = 2 >>> x [1, 2, 1]
注:不能为一个位置不存在的元素进行赋值。如果列表的长度为2,那么不能为索引为100的元素进行赋值。如果要那样做,就必须创建一个长度为101(或者更长)的列表。请参考本章“None、空列表和初始化”一节。
2.删除元素
从列表中删除元素也很容易:使用del语句实现。
>>> names = ["Alice", "Beth", "Cecil", "Dee-Dee", "Earl"] >>> del names[2] >>> names [‘Alice‘, ‘Beth‘, ‘Dee-Dee‘, ‘Earl‘]
注意Cecil是如何彻底消失的,并且列表的长度也从5变为了4。除了删除列表中的元素,del语句还能用于删除其他元素。它可以用于字典元素(请参考第四章)甚至是其他变量得删除操作,有关这方面的详细介绍,请参见第五章。
3.分片赋值
分片是一个非常强大的特性,分片赋值操作则更加显现它的强大。
>>> name = list("Perl") >>> name [‘P‘, ‘e‘, ‘r‘, ‘l‘] >>> name[2:] = list("ar") >>> name [‘P‘, ‘e‘, ‘a‘, ‘r‘]
程序可以一次为多个元素赋值了。可能有的读者会想:这有什么大不了的,难道就不能一次一个地赋吗?当然可以,但是在使用分片赋值时,可以使用与原序列不等长的序列将分片替换:
>>> name = list("Perl") >>> name[1:] = list("ython") >>> name [‘P‘, ‘y‘, ‘t‘, ‘h‘, ‘o‘, ‘n‘]
分片赋值语句可以在不需要替换任何原有元素的情况下插入新的元素:
>>> numbers = [1, 5] >>> numbers[1:1] = [2, 3, 4] >>> numbers [1, 2, 3, 4, 5]
这个程序只是“替换”了一个空的分片,因此实际的操作是插入了一个序列。以此类推,通过分片赋值来删除元素也是可行的。
>>> numbers [1, 2, 3, 4, 5] >>> numbers[1:4] = [] >>> numbers [1, 5]
上面的例子结果和del numbers[1:4]的一样。接下来请读者自己尝试利用1之外的步长,甚至是负数进行分片吧。
2.3.3 列表方法
之前的章节中已经介绍了什么是函数,那么现在来看看另外一个与函数密切相关的概念——方法。
方法是一个与某些对象有紧密联系的函数,对象可能是列表、数字,也可能是字符串或者其他类型的对象。一般来说,方法可以这样进行调用:
对象.方法(参数)
除了对象被放置到方法名之前,并且两者之间用一个点号隔开,方法调用与函数调用很类似。第七章将对方法到底是什么进行更详细的解释。列表提供了几个方法,用于检查或者修改其中的内容。
1.append
append方法用于在列表末尾追加新的对象:
>>> lst = [1, 2, 3] >>> lst.append(4) >>> lst [1, 2, 3, 4]
为什么我选择了如此糟糕的变量名lst,而不是使用list来表示一个列表呢?原因在于list是一个内建函数(实际上,从Python2.2开始,list就是一个类型而不是函数了。(tuple和str也是如此)如果想了解完整的说明,请参见9.3.2节)。如果使用list作为变量名,我就无法调用list函数了。根据给定的应用程序可以定义更好的变量名,像lst这样的变量名是毫无意义的。所以,如果需要定义一个价格列表,那么就应该使用prices、prices_of_eggs,或者pricesOfEggs作为变量名。
注意,下面的内容很重要:append方法和其他一些方法类似,只是在恰当位置修改原来的列表。这意味着,它不是简单地返回一个修改过的新列表——而是直接修改原来的列表。一般来说这正是你想要的,但是在某些情况下,这样也会带来其他麻烦。在本章稍后讲述sort方法时,我将再次讨论这个问题。
2.count
count方法统计某个元素在列表中出现的次数:
>>> ["to", "be", "or", "not", "to", "be"].count("to") 2 >>> x = [[1, 2], 1, 1, [2, 1, [1, 2]]] >>> x.count(1) 2 >>> x.count([1, 2]) 1
3.extend
extend方法可以在列表的末尾一次性追加另一个序列中的多个值。换句话说,可以用新的列表扩展原有的列表:
>>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> a.extend(b) >>> a [1, 2, 3, 4, 5, 6]
这个操作看起来很像连接操作,两者最主要的区别在于:extend方法修改了被扩展的序列(在这个例子中,就是a)。而原始的连接操作则不然,它会返回一个全新的列表:
>>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> a + b [1, 2, 3, 4, 5, 6] >>> a [1, 2, 3]
你可以看到连接的列表与之前例子中被扩展的列表是一样的,但是这一次它并没有被修改。这是因为原始的连接操作创建了一个包含a和b副本的新列表。如果需要如下例所示的操作,那么连接操作的效率会比extend方法低。
>>> a = a + b
同样,这里也不是一个原位置操作,它并不会修改原来的列表。
我们可以使用分片赋值来实现相同的结果:
>>> a = [1, 2, 3] >>> b = [4, 5, 6] >>> a[len(a):] = b >>> a [1, 2, 3, 4, 5, 6]
虽然这么做是可行的,但是代码的可读性就不如使用extend方法了。
4.index
index方法用于从列表中找出某个值第一个匹配项的索引位置:
>>> knights = ["We", "are", "the", "knights", "who", "say", "ni"] >>> knights.index("who") 4 >>> knights.index("herring") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: ‘herring‘ is not in list
当搜索单词who的时候,就会发现它在索引号为4的位置。然而,当搜索"herring"的时候,就会引发一个异常,因为这个单词没有被找到。
5.insert
insert方法用于将对象插入列表中:
>>> numbers = [1, 2, 3, 5, 6, 7] >>> numbers.insert(3, "four") >>> numbers [1, 2, 3, ‘four‘, 5, 6, 7]
与extend方法一样,insert方法的操作也可以用分片赋值来实现。
>>> numbers = [1, 2, 3, 5, 6, 7] >>> numbers[3:3] = ["four"] >>> numbers [1, 2, 3, ‘four‘, 5, 6, 7]
这样做有点新奇,但是它的可读性绝对不如insert方法。
6.pop
pop方法会移除列表中的一个元素(默认是最后一个),并且返回该元素的值:
>>> x = [1, 2, 3] >>> x.pop() 3 >>> x [1, 2] >>> x.pop(0) 1 >>> x [2]
注:pop方法是唯一一个既能修改列表又返回元素值(除了None)的列表方法。
使用pop方法可以实现一种常见的数据结构——栈。栈的原理就像堆放盘子那样。只能在顶部放盘子,同样,也只能从顶部拿走一个盘子。最后被放入栈堆的最先被移除(这个原则成为LIFO,即后进先出)。
对于上述的两个栈操作(放入和移出),它们有大家都认可的称谓——入栈(push)和出栈(pop)。Python没有入栈方法,但可以使用append方法来代替。pop方法和append方法的操作结果恰好相反,如果入栈(或者追加)刚刚出栈的值,最后得到的结果还是原来的栈。
>>> x = [1, 2, 3] >>> x.append(x.pop()) >>> x [1, 2, 3]
注:如果需要实现一个先进先出(FIFO)的队列(queue),那么可以使用insert(0, ...)来代替append方法。或者,也可以继续使用append方法,但必须用pop(0)来代替pop()。更好的解决方案是使用collection模块中的deque对象。要了解更详细的信息,请参见第十章
7.remove
remove方法用于移除列表中某个值的第一个匹配项:
>>> x = ["to", "be", "or", "not", "to", "be"] >>> x.remove("be") >>> x [‘to‘, ‘or‘, ‘not‘, ‘to‘, ‘be‘] >>> x.remove("bee") Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
可以看到:只有第一次出现的值被移除了,而不存在于列表中的值(比如例子中的"bee")是不会移除的。
值得注意的是,remove是一个没有返回值的原位置改变的方法。它修改了列表却没有返回值,这与pop方法相反。
8.reverse
reverse方法将列表中的元素反向存放(我猜你们对此不会特别惊讶):
>>> x = [1, 2, 3] >>> x.reverse() >>> x [3, 2, 1]
请注意,该
以上是关于列表和元组)的主要内容,如果未能解决你的问题,请参考以下文章