Python学习教程(二)——序列之列表和元组
2017-10-27 23:04
555 查看
1. 序列
1.1. 序列概览
在Python中,最基本的数据结构是序列(sequence),序列中的每一个元素被分配一个序号——即元素的位置,也成为索引,从0开始计数。Python中有6种内建的序列:列表、元组、字符串、Unicode字符串、buffer对象、xrange对象。所谓“序列概览”讲的是所有序列类型都通用的操作。
列表和元组的主要区别:列表可以修改,元组则不能。
下面就是一个序列的例子:
ylh = ['yangliehui',28]
序列也可以包含其他序列:
>>> ylh = ['yangliehui',28] >>> zs = ['zhangsan',30] >>> names = [ylh,zs] >>> names [['yangliehui', 28], ['zhangsan', 30]]
1.2. 通用序列操作
1.2.1. 索引
序列中所有的编号都是从0开始的,比如下面的字符串就是为字符组成的序列。>>> greeting = 'Hello' >>> greeting[0] 'H'
序列的索引可以是从左向右,此时第一个是0,往右加1;可以可以是从右向左,最右边-1开始,往左减1;如下:
>>> greeting = 'Hello!' >>> greeting[-1] '!'
序列字面值可以直接使用索引而不需要一个变量引用(这适用于其他序列而不仅限于字符串),如下:
>>> 'Hello!'[0] 'H' >>> 'Hello!'[-1] '!'
也可以直接对返回结果操作:
>>> year = raw_input('Year=')[3] Year=2017 >>> year '7'
1.2.2. 分片
与索引类似,索引用来访问单个元素,而分片用来访问一定范围内的元素。格式如下:[参数1:参数2]:参数1表示要提取的第一个元素的编号,第二个参数表示分片之后剩余部分中第一个元素的标号。
>>> str = 'abcdefg' >>> str[1:5] 'bcde'
上面的代码可以用下图表示:
>>> str = 'abcdefg' >>> str[-6:-2] 'bcde'
上面的代码可以用下图表示:
我们要注意下面的情况,如果自左向右取数,索引7指向的元素并不存在,但却是在最后一个元素之后,是没有问题的。但是如果从结尾自右向左取数,显然第二个参数写-1或写0都是不对的。尤其例子中[-6:0]的写法,只要顺序写反了都会返回空字符串。
>>> str = 'abcdefg' >>> str[1:7] 'bcdefg'
上面的代码可以用下图表示:
>>> str = 'abcdefg' >>> str[-6:-1] 'bcdef' >>> str[-6:0] ''
上面的代码可以用下图表示:
那么上述描述的情况就无解了吗?其实我们可以有另一种写法,空一个参数:
>>> str = 'abcdefg' >>> str[-6:] 'bcdefg' >>> str[1:] 'bcdefg'
两个参数都写空也是可以的,这样将会返回整个序列:
>>> str = 'abcdefg' >>> str[:] 'abcdefg'
现在介绍分片的第三个参数,步长,看一段程序:
>>> numbers=[1,2,3,4,5,6,7,8,9,10] >>> numbers[0:10:1] [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> numbers[0:10:2] [1, 3, 5, 7, 9]
以上就是步长,当步长为2时会跳过一个元素;
步长不能为0,但是步长可以为负数,这时从从右向左取数:
>>> numbers=[1,2,3,4,5,6,7,8,9,10] >>> numbers[::-1] [10, 9, 8, 7, 6, 5, 4, 3, 2, 1] >>> numbers[::-2] [10, 8, 6, 4, 2]
但这里要注意,如果步长为负数,那么第一第二个参数提取元素的顺序也是倒序的,如下:
>>> numbers=[1,2,3,4,5,6,7,8,9,10] >>> numbers[8:3:-1] #我们看到参数的顺序是先8后3 [9, 8, 7, 6, 5] >>> numbers[10:0:-2] #我们看到参数的顺序是先10后0 [10, 8, 6, 4, 2] >>> numbers[0:10:-2] #反过来试试?发现顺序错误,返回空字符串 [] >>> numbers[5::-2] [6, 4, 2] >>> numbers[:5:-2] [10, 8]
1.2.3. 序列相加
序列相加即是连接操作:>>> [1,2,3]+[4,5,6] [1, 2, 3, 4, 5, 6] >>> 'Hello,' + 'World!' 'Hello,World!' >>> [1,2,3] + 'World!' Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: can only concatenate list (not "str") to list
两种类型相同的序列才可以相加,所有上述[1,2,3]+’World!’报错。
1.2.4. 序列乘法
我们先来看一个例子:>>> 'python'*5 'pythonpythonpythonpythonpython' >>> [23]*4 [23, 23, 23, 23]
None是一个Python的内建值,表示“什么也没有”。初始化一个长度为10的列表:
>>> sequence = [None] * 10 >>> sequence [None, None, None, None, None, None, None, None, None, None]
1.2.5. 成员资格
in运算符:检查一个值是否在序列中;>>> permissions = 'rw' >>> 'w' in permissions True >>> 'x' in permissions False >>> user = ['mlh','foo','bar'] >>> raw_input('Enter your user name:') in user Enter your user name:mlh True >>> subject = '$$$ Get rich now!!! $$$' >>> '$$$' in subject True
对于字符串,in可以查找子字符串:
>>> str = 'hello' >>> 'hel' in str True
1.2.6. 长度、最小值、最大值
len、min、max函数。>>> numbers=[100,34,678] >>> len(numbers) 3 >>> max(numbers) 678 >>> min(numbers) 34 >>> max(2,3) 3 >>> min(9,3,4,5) 3
1.3. 序列涉及到的一些内建函数
1.3.1. reversed(seq)
对序列反向迭代。与列表的reverse()方法不同,这个函数返回的是一个迭代器对象,对迭代器的使用这里不涉及,后续会有讲解。
>>> x = [1,2,3] >>> y = reversed(x) >>> list(y) [3, 2, 1]
1.3.2. sorted(seq)
返回已排序的包含seq所有元素的列表。与列表的sort()方法不同,列表sort方法是在原列表中修改,并且不会有返回值。而该函数不会对原列表修改,并且返回一个已经排序的列表副本:
>>> x = [6,5,2,8,9,2] >>> y = sorted(x) >>> x [6, 5, 2, 8, 9, 2] >>> y [2, 2, 5, 6, 8, 9]
并且这个函数适用于所有的序列类型,并且总是返回一个列表:
>>> sorted('hello') ['e', 'h', 'l', 'l', 'o'] >>> sorted([4,1,2,7,0]) [0, 1, 2, 4, 7] >>> sorted((4,1,2,6,1)) [1, 1, 2, 4, 6]
2. 列表
2.1. 列表的基础操作
列表是可变的——可以改变列表的内容。2.1.1. 创建列表
list函数:创建列表。适用于所有的序列类型,而不只是字符串。下面只是以字符串举例。由于字符串不能修改,所以可以根据字符串创建列表。利用list函数可以实现。>>> list('hello') ['h', 'e', 'l', 'l', 'o'] >>> p1 = 'hello' >>> list(p1) ['h', 'e', 'l', 'l', 'o'] >>> p3 = (432,643,745) >>> list(p3) [432, 643, 745]
与之相反操作的函数为join。把列表转换为字符串:
>>> list_str = list('hello') >>> ''.join(list_str) 'hello'
2.1.2. 改变列表
>>> x = [1,1,1] >>> x[1] = 2 >>> x [1, 2, 1]
2.1.3. 删除元素
del语句:>>> names = ['zhangsan','lisi','yangliehui'] >>> del names[1] >>> names ['zhangsan', 'yangliehui']
2.1.4. 分片赋值
>>> name = list('yangliehui') >>> name ['y', 'a', 'n', 'g', 'l', 'i', 'e', 'h', 'u', 'i'] >>> name[7:]=list('yan') >>> name ['y', 'a', 'n', 'g', 'l', 'i', 'e', 'y', 'a', 'n']
在上面的例子中,name[7:]=’yan’ 这样写也会是同样的结果,因为string也是序列类型,当把string作为参数进行分片赋值给列表时会把字符串作为列表来处理,自动转换为列表。只是使用list函数转换一下更易读。看如下的例子:
>>> number = [None]*10 >>> number [None, None, None, None, None, None, None, None, None, None] >>> number[:] = '0123456789' >>> number ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
即使没有对’0123456789’做list转换,同样可以作为列表通过分片赋值。
分片赋值的好处是可以使用与原序列不等长的序列将分片替换:
>>> name = list('ylh') >>> name[0:] = list('yangliehui') >>> name ['y', 'a', 'n', 'g', 'l', 'i', 'e', 'h', 'u', 'i']
上面的例子中,name有三个字符的序列,替换为了十个字符的序列。
还可以插入新的元素:
>>> 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]
还可以还步长配合使用:
>>> number = [1,2,3,4,5,6,7,8,9,10] >>> number[::2] = ['a','b','c','d','e'] >>> number ['a', 2, 'b', 4, 'c', 6, 'd', 8, 'e', 10]
2.2. 列表常用方法
2.2.1. append
列表末尾加新的对象;>>> num = [1,2,3] >>> num.append(4) >>> num [1, 2, 3, 4] >>> str = ['a','b','c'] >>> str.append('d') >>> str ['a', 'b', 'c', 'd'] >>> >>> num.append('e') >>> num [1, 2, 3, 4, 'e']
注意可以追加不同类型的对象到列表中。
append是在原列表基础上修改列表内容。
2.2.2. count
统计某个元素在列表中出现的次数。>>> ['a','a','b','c'].count('a') 2 >>> x = [[1,2],1,1,[2,1,[1,2]]] >>> x.count(1) 2 >>> x.count([1,2]) 1
2.2.3. extend
在列表末尾追加另一个序列中的多个值。>>> a = [1,2,3,4] >>> b = [5,6,7,8] >>> a.extend(b) >>> a [1, 2, 3, 4, 5, 6, 7, 8]
它与原始的连接操作不同之处在于extend修改了被扩展的列表,而连接则返回一个全新的列表。
>>> a = [1,2,3,4] >>> b = [5,6,7,8] >>> a + b [1, 2, 3, 4, 5, 6, 7, 8] >>> a [1, 2, 3, 4]
可以看到a的值并没有变化。
当然我们也可以这样做,但是这只是创建了一个包含a和b的新列表,并重新赋给了a,不是一个原位置操作,不会修改原来的列表:
>>> a = a + b >>> a [1, 2, 3, 4, 5, 6, 7, 8]
所以效率不如extend。
如果要实现和extend一样的原位置操作,可以如下:
>>> a = [1,2,3] >>> b = [4,5,6] >>> a[len(a):] = b >>> a [1, 2, 3, 4, 5, 6]
这样做的缺点是可读性差,不如使用extend。
2.2.4. index
某个值第一个匹配项的索引位置:>>> names = ['zhangs','lis','ylh','wangw','ylh','jim'] >>> names.index('ylh') 2
当没有找到时会报错:
>>> names.index('abc') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: 'abc' is not in list
2.2.5. insert
insert(index,object) index表示对象插入后在新列表中的索引位置。这种方式同样也是修改了现有的列表,而不是创建新的列表。>>> number = [1,2,3,4,5,6,7,8] >>> number.insert(3,'ins') >>> number [1, 2, 3, 'ins', 4, 5, 6, 7, 8]
实现同样的功能,我们也可以使用分片:
>>> number = [1,2,3,4,5,6,7,8] >>> number[3:3] = ['ins'] >>> number [1, 2, 3, 'ins', 4, 5, 6, 7, 8]
注意,插入的必须是列表类型。 且可读性没有insert方法好。
2.2.6. pop
注意:它是唯一一个既能修改列表又返回新元素值(除了None)的列表方法pop方法类似入栈出栈中的出栈。当调用pop时返回最上面的列表元素,并修改了原来的原来的列表。如下:
>>> number = [1,2,3] >>> number.pop() 3 >>> number [1, 2]
Python中并没有单独的入栈列表方法,但我们可以使用append来代替:
>>> number.append(3) >>> number [1, 2, 3]
下面的例子中,程序先出栈返回3并修改了列表为[1,2],随后又出栈了出栈时返回的[3]。 所以得到的还是原来的列表。
>>> number [1, 2, 3] >>> number.append(number.pop()) >>> number [1, 2, 3]
所以上面append和pop方法配合使用,实现了栈的结构——后进先出。
其实pop方法还可以有参数的,参数表示要移除的元素在列表中的索引位置,如下:
>>> number = [1,2,3,4,5,6] >>> number.pop(2) 3 >>> number [1, 2, 4, 5, 6]
因此如果我们要实现一个queue,即先进先出,有以下两种方法:
1. insert(0,x) 和 pop() 配合使用:
>>> number = [] >>> number.insert(0,0) >>> number.insert(0,1) >>> number.insert(0,2) >>> number.pop() 0 >>> number.pop() 1 >>> number.pop() 2 >>> number []
append 和 pop(0)配合使用:
>>> number = [] >>> number.append(0) >>> number.append(1) >>> number.append(2) >>> number.pop(0) 0 >>> number.pop(0) 1 >>> number.pop(0) 2 >>> number []
2.2.7. remove
移除列表中某个值的第一个匹配项:>>> x = ['aaa','bb','aaa','cc'] >>> x.remove('aaa') >>> x ['bb', 'aaa', 'cc'] >>> x.remove('dd') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
只会移除第一个。并且当找不到参数内的元素时会提示错误。
它与pop不同的是,remove并不会返回被移除的元素值,它是没有返回值的。
相同的是,都在原列表上修改值;
2.2.8. reverse
反向存放。>>> x = [1,2,3,4] >>> x.reverse() >>> x [4, 3, 2, 1]
原列表上修改,无返回值。
2.2.9. sort
在原位置上对列表进行排序。并不是创建一个已排序的副本。该方法也没有返回值。>>> x = [4,2,6,8,1,3,9] >>> x.sort() >>> x [1, 2, 3, 4, 6, 8, 9]
关于排序的高级应用:
sort([func])
func——指定比较函数,按照该函数的方法进行排序。
这个指定的函数可以自建,比如我们定义一个函数compare(x,y),实现比如当x>y时返回1,当x
>>> x = [3,1,4,6,1,5,2,8] >>> x.sort(cmp) >>> x [1, 1, 2, 3, 4, 5, 6, 8]
sort([key or reverse])
参数key与cmp类似,需要提供一个排序过程中使用的函数。该函数不能直接确定对象的大小,而是为每个元素创建一个键,然后所有元素根据键来排序:
>>> x = ['aaaaaa','aa','a','aa'] >>> x.sort(key=len) >>> x ['a', 'aa', 'aa', 'aaaaaa']
以元素的len为键,然后进行排序。
参数reverse,指定是否反向排序。
>>> x = [2,5,1,7,3,9,2,5] >>> x.sort(reverse=False) >>> x [1, 2, 2, 3, 5, 5, 7, 9] >>> x.sort(reverse=True) >>> x [9, 7, 5, 5, 3, 2, 2, 1]
3. 元组
序列的一种,不能修改。(其实字符串也是这样的)3.1. 创建元组
>>> #直接逗号分隔 ... 1,2,3 (1, 2, 3) >>> #圆括号 ... (1,2,3) (1, 2, 3) >>> #空元组 ... () () >>> #创建一个值的元组,我们发现必须要在元素后面加一个逗号 ... 23, (23,) >>> (23) 23 >>> (23,) (23,)
逗号的作用,一个逗号,结果千差万别:
>>> 3*(40+2) 126 >>> 3*(40+2,) (42, 42, 42)
3.2. tuple函数
与list函数类似,把序列类型值作为参数返回的是元组。>>> tuple('abc') ('a', 'b', 'c') >>> tuple([1,2,4]) (1, 2, 4) >>> tuple((1,2,3)) (1, 2, 3)
元组可以使用与列表同样的分片操作,元组的分片还是元组,就像列表的分片还是列表一样。
>>> x = (1,2,3,4) >>> x[1:3] (2, 3)
相关文章推荐
- Python基础教程 第2章: 列表和元组 学习笔记
- 【Python基础教程】第2章 列表和元组-2.4元组:不可变序列
- Python常用的内置序列结构(列表、元组、字典)学习笔记
- .Net程序员之Python基础教程学习----列表和元组 [First Day]
- Python常用的内置序列结构(列表、元组、字典)学习笔记
- Python基础教程学习笔记 第二章 列表和元组
- python学习(列表、字典、元组、序列)
- python 学习笔记 二 序列, 列表, 元组, 字符串
- Python基础教程学习比较----第二章 列表和元组
- 【Python基础教程】第2章 列表和元组-2.2通用序列操作
- python核心编程学习记录之序列(字符串元组列表)
- Python学习三---序列、列表、元组
- python基础教程__列表、元组、字符串和字典
- Python学习_03_列表、元组、字符串
- Python学习之路2 - 列表和元组
- Python 学习笔记 -- 变量、元组、列表、字典和集合
- python学习之路二(字符串,字典,序列和元组)
- python关于序列中的列表和元组总结
- python学习笔记_列表,元组
- 简明python教程 --C++程序员的视角(四):容器类型(字符串、元组、列表、字典)和参考