--- layout: post # 使用的布局(不需要改) title: 「Python教程08」列表 # 标题 subtitle: Python学习笔记 #副标题 date: 2019-09-26 # 时间 author: Duter2016 # 作者 header-img: img/post-bg-swift2.jpg #这篇文章标题背景图片 catalog: true # 是否归档 music-id: # 网易云音乐单曲嵌入 music-idfull: # 网易云音乐歌单嵌入 tags: #标签 - Python - 教程 --- 1、列表值看起来像这样:['cat', 'bat', 'rat', 'elephant']。就像字符串值用引号来标记字符串的起止一样,列表用左方括号开始,右方括号结束,即[]。列表中的值也称为“表项”。表项用逗号分隔。 2、假定列表['cat', 'bat', 'rat', 'elephant']保存在名为spam的变量中。Python代码spam[0]将求值为'cat',spam[1]将求值为'bat',依此类推。列表后面方括号内的整数被称为“下标”。列表中第一个值的下标是0,第二个值的下标是1,第三个值的下标是2,依此类推。图4-1展示了一个赋给spam的列表值,以及下标表达式的求值结果。 ![title](https://raw.githubusercontent.com/Duter2016/GitNote-images/master/Images/2019/04/15/1555335721972-1555335721975.png) ``` >>> ['cat', 'bat', 'rat', 'elephant'][3] 'elephant' ``` 虽然下标从0开始并向上增长,但也可以用负整数作为下标。整数值−1指的是列表中的最后一个下标,−2指的是列表中倒数第二个下标,以此类推。 3、列表中的值,可以通过多重下标来访问,像这样: ``` >>> spam = [['cat', 'bat'], [10, 20, 30, 40, 50]] >>> spam[0] ['cat', 'bat'] >>> spam[0][1] 'bat' >>> spam[1][4] 50 ``` 第一个下标表明使用哪个列表值,第二个下标表明该列表值中的值。例如,spam[0][1]打印出'bat',即第一个列表中的第二个值。如果只使用一个下标,程序将打印出该下标处的完整列表值。 4、利用切片获得子列表 • spam[1:4]是一个列表和切片(两个整数)。 在一个切片中,第一个整数是切片开始处的下标。第二个整数是切片结束处的下标。切片向上增长,直至第二个下标的值,但不包括它。切片求值为一个新的列表值。在交互式环境中输入以下代码: ``` >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[0:4] ['cat', 'bat', 'rat', 'elephant'] >>> spam[1:3] ['bat', 'rat'] >>> spam[0:-1] ['cat', 'bat', 'rat'] ``` 作为快捷方法,你可以省略切片中冒号两边的一个下标或两个下标。省略第一个下标相当于使用0,或列表的开始。省略第二个下标相当于使用列表的长度,意味着分片直至列表的末尾。在交互式环境中输入以下代码: ``` >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[:2] ['cat', 'bat'] >>> spam[1:] ['bat', 'rat', 'elephant'] >>> spam[:] ['cat', 'bat', 'rat', 'elephant'] ``` 5、用下标改变列表中的值: 例如,spam[1] = 'aardvark'意味着“将列表spam下标1处的值赋值为字符串'aardvark'。在交互式环境中输入以下代码: ``` >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam[1] = 'aardvark' >>> spam ['cat', 'aardvark', 'rat', 'elephant'] >>> spam[2] = spam[1] >>> spam ['cat', 'aardvark', 'aardvark', 'elephant'] >>> spam[-1] = 12345 >>> spam ['cat', 'aardvark', 'aardvark', 12345] ``` 6、列表连接和列表复制: +操作符可以连接两个列表,得到一个新列表,就像它将两个字符串合并成一个新字符串一样。*操作符可以用于一个列表和一个整数,实现列表的复制。在交互式环境中输入以下代码: ``` >>> [1, 2, 3] + ['A', 'B', 'C'] [1, 2, 3, 'A', 'B', 'C'] >>> ['X', 'Y', 'Z'] * 3 ['X', 'Y', 'Z', 'X', 'Y', 'Z', 'X', 'Y', 'Z'] >>> spam = [1, 2, 3] >>> spam = spam + ['A', 'B', 'C'] >>> spam [1, 2, 3, 'A', 'B', 'C'] ``` 7、从列表中删除值: del语句将删除列表中下标处的值,表中被删除值后面的所有值,都将向前移动一个下标。例如,在交互式环境中输入以下代码: ``` >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> del spam[2] >>> spam ['cat', 'bat', 'elephant'] >>> del spam[2] >>> spam ['cat', 'bat'] ``` del语句也可用于一个简单变量,删除它,作用就像是“取消赋值”语句。如果在删除之后试图使用该变量,就会遇到NameError错误,因为该变量已不再存在。 8、列表用于循环: 循环是针对一个列表或类似列表中的每个值,重复地执行代码块。例如,如果执行以下代码: `for i in range(4):` print(i)程序的输出将是: ``` 0 1 2 3 ``` 这是因为range(4)的返回值是类似列表的值。Python认为它类似于[0, 1, 2, 3]。下面的程序和前面的程序输出相同: ``` for i in [0, 1, 2, 3]: print(i) ``` 例如:使用一个列表保存用户输入的任意多的猫的名字。在新的文件编辑器窗口中,输入以下代码并保存为allMyCats2.py。 ``` catNames = [] while True: print('Enter the name of cat ' + str(len(catNames) + 1) + ' (Or enter nothing to stop.):') name = input() if name == '': break catNames = catNames + [name] # list concatenation print('The cat names are:') for name in catNames: print(' ' + name) ``` 运行这个程序,输出看起来像这样: ``` Enter the name of cat 1 (Or enter nothing to stop.): Zophie Enter the name of cat 2 (Or enter nothing to stop.): Pooka Enter the name of cat 3 (Or enter nothing to stop.): Simon Enter the name of cat 4 (Or enter nothing to stop.): Lady Macbeth Enter the name of cat 5 (Or enter nothing to stop.): Fat-tail Enter the name of cat 6 (Or enter nothing to stop.): Miss Cleo Enter the name of cat 7 (Or enter nothing to stop.): The cat names are: Zophie Pooka Simon Lady Macbeth Fat-tail Miss Cleo ``` 9、 in和not in操作符 利用in和not in操作符,可以确定一个值否在列表中。像其他操作符一样,in和not in用在表达式中,连接两个值:一个要在列表中查找的值,以及待查找的列表。这些表达式将求值为布尔值。在交互式环境中输入以下代码: ``` >>> 'howdy' in ['hello', 'hi', 'howdy', 'heyas'] True >>> spam = ['hello', 'hi', 'howdy', 'heyas'] >>> 'cat' in spam False >>> 'howdy' not in spam False >>> 'cat' not in spam True ``` 10、多重赋值: 可以通过列表进行多重赋值,输入下面的代码: ``` >>> cat = ['fat', 'black', 'loud'] >>> size, color, disposition = cat ``` 变量的数目和列表的长度必须严格相等,否则Python将给出ValueError。 11、增强的赋值操作符: 针对+、-、*、/和%操作符,都有增强的赋值操作符,如表4-1所示。 **表4-1 增强的赋值操作符** 增强的赋值语句| 等价的赋值语句 -|- spam += 1| spam = spam + 1 spam -= 1| spam = spam - 1 spam *= 1| spam = spam * 1 spam /= 1| spam = spam / 1 spam %= 1| spam = spam % 1 +=操作符也可以完成字符串和列表的连接,*=操作符可以完成字符串和列表的复制。在交互式环境中输入以下代码: ``` >>> spam = 'Hello' >>> spam += ' world!' >>> spam 'Hello world!' >>> bacon = ['Zophie'] >>> bacon *= 3 >>> bacon ['Zophie', 'Zophie', 'Zophie'] ``` 12、**index()方法在列表中查找值:** 列表值有一个index()方法,可以传入一个值,如果该值存在于列表中,就返回它的下标。如果该值不在列表中,Python就报ValueError。在交互式环境中输入以下代码: ``` >>> spam = ['hello', 'hi', 'howdy', 'heyas'] >>> spam.index('hello') 0 >>> spam.index('heyas') 3 >>> spam.index('howdy howdy howdy') Traceback (most recent call last): File "", line 1, in spam.index('howdy howdy howdy') ValueError: 'howdy howdy howdy' is not in list ``` 如果列表中存在重复的值,就返回它第一次出现的下标。 13、 **用append()和insert()方法在列表中添加值** 要在列表中添加新值,就使用append()和 insert()方法。在交互式环境中输入以下代码,对变量spam中的列表调用append()方法: ``` >>> spam = ['cat', 'dog', 'bat'] >>> spam.append('moose') >>> spam ['cat', 'dog', 'bat', 'moose'] ``` 前面的append()方法调用,将参数添加到列表末尾。 insert()方法可以在列表任意下标处插入一个值。insert()方法的第一个参数是新值的下标,第二个参数是要插入的新值。在交互式环境中输入以下代码: ``` >>> spam = ['cat', 'dog', 'bat'] >>> spam.insert(1, 'chicken') >>> spam ['cat', 'chicken', 'dog', 'bat'] ``` 请注意,代码是spam.append('moose')和spam.insert(1, 'chicken'),而不是spam = spam.append('moose')和spam = spam.insert(1, 'chicken')。append()和insert()都不会将spam的新值作为其返回值(实际上,append()和insert()的返回值是None,所以你肯定不希望将它保存为变量的新值)。但是,列表被“当场”修改了。 方法属于单个数据类型。append()和insert()方法是列表方法,只能在列表上调用,不能在其他值上调用,例如字符串和整型。 14、**remove()方法从列表中删除值:** 给 remove()方法传入一个值,它将从被调用的列表中删除。在交互式环境中输入以下代码: ``` >>> spam = ['cat', 'bat', 'rat', 'elephant'] >>> spam.remove('bat') >>> spam ['cat', 'rat', 'elephant'] ``` 如果该值在列表中出现多次,只有第一次出现的值会被删除。 如果知道想要删除的值在列表中的下标,del语句就很好用。如果知道想要从列表中删除的值,remove()方法就很好用。 15、 **用sort()方法将列表中的值排序** 数值的列表或字符串的列表,能用sort()方法排序。例如,在交互式环境中输入以下代码: ``` >>> spam = [2, 5, 3.14, 1, -7] >>> spam.sort() >>> spam [-7, 1, 2, 3.14, 5] >>> spam = ['ants', 'cats', 'dogs', 'badgers', 'elephants'] >>> spam.sort() >>> spam ['ants', 'badgers', 'cats', 'dogs', 'elephants'] ``` 也可以指定reverse关键字参数为True,让sort()按逆序排序。在交互式环境中输入以下代码: ``` >>> spam.sort(reverse=True) >>> spam ['elephants', 'dogs', 'cats', 'badgers', 'ants'] ``` **关于sort()方法,你应该注意3件事。** 首先,sort()方法当场对列表排序。不要写出spam = spam.sort()这样的代码,试图记录返回值。 其次,不能对既有数字又有字符串值的列表排序,因为Python不知道如何比较它们。在交互式环境中输入以下代码,注意TypeError错误: ``` >>> spam = [1, 3, 2, 4, 'Alice', 'Bob'] >>> spam.sort() Traceback (most recent call last): File "", line 1, in spam.sort() TypeError: unorderable types: str() < int() ``` 第三,sort()方法对字符串排序时,使用“ASCII字符顺序”,而不是实际的字典顺序。这意味着大写字母排在小写字母之前。因此在排序时,小写的a在大写的Z之后。例如,在交互式环境中输入以下代码: ``` >>> spam = ['Alice', 'ants', 'Bob', 'badgers', 'Carol', 'cats'] >>> spam.sort() >>> spam ['Alice', 'Bob', 'Carol', 'ants', 'badgers', 'cats'] ``` 如果需要按照普通的字典顺序来排序,就在sort()方法调用时,将关键字参数key设置为str.lower。 ``` >>> spam = ['a', 'z', 'A', 'Z'] >>> spam.sort(key=str.lower) >>> spam ['a', 'A', 'z', 'Z'] ``` 这将导致sort()方法将列表中所有的表项当成小写,但实际上并不会改变它们在列表中的值。 16、**修改字符串:** “改变”一个字符串的正确方式,是使用切片和连接。构造一个“新的”字符串,从老的字符串那里复制一些部分。在交互式环境中输入以下代码: ``` >>> name = 'Zophie a cat' >>> newName = name[0:7] + 'the' + name[8:12] >>> name 'Zophie a cat' >>> newName 'Zophie the cat' ``` 我们用[0:7]和[8:12]来指那些不想替换的字符。请注意,原来的'Zophie a cat'字符串没有被修改,因为字符串是不可变的。注意空格也占一个下标值。 17、 **元组数据类型** 除了两个方面,“元组”数据类型几乎与列表数据类型一样。首先,元组输入时用圆括号(),而不是用方括号[]。例如,在交互式环境中输入以下代码: ``` >>> eggs = ('hello', 42, 0.5) >>> eggs[0] 'hello' >>> eggs[1:3] (42, 0.5) >>> len(eggs) 3 ``` 但元组与列表的主要区别还在于,元组像字符串一样,是不可变的。元组不能让它们的值被修改、添加或删除。在交互式环境中输入以下代码,注意TypeError出错信息: ``` >>> eggs = ('hello', 42, 0.5) >>> eggs[1] = 99 Traceback (most recent call last): File "", line 1, in eggs[1] = 99 TypeError: 'tuple' object does not support item assignment ``` 如果元组中只有一个值,你可以在括号内该值的后面跟上一个逗号,表明这种情况。否则,Python将认为,你只是在一个普通括号内输入了一个值。逗号告诉Python,这是一个元组(不像其他编程语言,Python接受列表或元组中最后表项后面跟的逗号)。在交互式环境中,输入以下的type()函数调用,看看它们的区别: ``` >>> type(('hello',)) >>> type(('hello')) ``` 18、 **用list()和tuple()函数来转换类型** 正如str(42)将返回'42',即整数42的字符串表示形式,函数list()和tuple()将返回传递给它们的值的列表和元组版本。在交互式环境中输入以下代码,注意返回值与传入值是不同的数据类型: ``` >>> tuple(['cat', 'dog', 5]) ('cat', 'dog', 5) >>> list(('cat', 'dog', 5)) ['cat', 'dog', 5] >>> list('hello') ['h', 'e', 'l', 'l', 'o'] ``` 如果需要元组值的一个可变版本,将元组转换成列表就很方便。 19、 **copy模块的copy()和deepcopy()函数** 第一个函数copy.copy(),可以用来复制列表或字典这样的可变值,而不只是复制引用。在交互式环境中输入以下代码: ``` >>> import copy >>> spam = ['A', 'B', 'C', 'D'] >>> cheese = copy.copy(spam) >>> cheese[1] = 42 >>> spam ['A', 'B', 'C', 'D'] >>> cheese ['A', 42, 'C', 'D'] ``` 现在spam和cheese变量指向独立的列表,这就是为什么当你将42赋给下标7时,只有cheese中的列表被改变。在图4-7中可以看到,两个变量的引用ID数字不再一样,因为它们指向了独立的列表。 如果要复制的列表中包含了列表,那就使用copy.deepcopy()函数来代替。deepcopy()函数将同时复制它们内部的列表。