Python第三课(序列之列表)
- 在上一课中已经说明了列表是什么,从本质上来说列表在Python中是一种数据结构,是一个通过称之为索引的序号标记的有序的许多元素组成的集合。列表中的元素是可以被改变的,这个特性是列表比元组更加灵活之处,因此列表也被更加广泛的使用。
1.创建一个列表
Python中这些数据结构的创建非常的简单,name=[1,2,3]就完成了一个名称为name,由三个元素1,2,3组成的列表;或者在Python交互解释器中直接输入中括号包含列表的元素;但是不将列表赋值给变量在使用起来会非常不方便所以还是使用变量名称=列表的方法来创建列表比较好。
1 >>> num=[1,2,3,4,5,6] 2 >>> [1,2,3,4,5,6,7] 3 [1, 2, 3, 4, 5, 6, 7]
2.list函数
使用list函数可以根据序列创建列表,字符串和元组不能被修改,所以可以根据字符串或者元组创建一个列表进行修改,然后在根据修改后的字符串或者元组赋值给原来的变量。
1 >>> name='chine' 2 >>> num=(1,2,3) 3 >>> list(name) ##根据字符串创建列表 4 ['c', 'h', 'i', 'n', 'e'] 5 >>> list(num) ##根据元组创建列表 6 [1, 2, 3]
- 列表的基本操作
1.修改列表:元素赋值
使用普通的赋值语句就可以对列表中的元素赋值,使用索引来为某个明确的元素赋值。不能为一个不存在的元素赋值
1 >>> name=['lufei','suolong','namei','shanzhi','qiaoba','luobin'] 2 >>> name[2]='haizeiwang' 3 >>> name 4 ['lufei', 'suolong', 'haizeiwang', 'shanzhi', 'qiaoba', 'luobin'] #索引为2的元素的值已经改变
2.删除元素
使用del函数来删除列表中的元素,del函数也可以删除其他的数据结构中的元素。使用del函数可以删除列表中的单个元素、多个元素,可以使用分片删除列表中的多个元素。
1 >>> name 2 ['lufei', 'suolong', 'haizeiwang', 'shanzhi', 'qiaoba', 'luobin'] 3 >>> del(name[3]) #删除索引为3的元素-删除单个元素 4 >>> name 5 ['lufei', 'suolong', 'haizeiwang', 'qiaoba', 'luobin'] 6 >>> del (name[1],name[2]) #删除多个元素,每个元素表达之间使用逗号隔开 7 >>> name 8 ['lufei', 'haizeiwang', 'luobin'] 9 >>> del(name[1:]) #使用分片操作删除多个元素 10 >>> name 11 ['lufei']
3.分片赋值
分片赋值特别强大,提现在它操作起来特别的灵活,以至于列表的其他操作方法也可以使用分片赋值来实现。这里仅说明分片赋值的使用,在说明其它操作时同时用分片对其它操作的实现进行说明。
1 >>> name 2 ['lufei'] 3 >>> name[1:1]='suolong' 4 >>> name 5 ['lufei', 's', 'u', 'o', 'l', 'o', 'n', 'g'] 6 >>> name[1:1]=['suolong'] 7 >>> name 8 ['lufei', 'suolong', 's', 'u', 'o', 'l', 'o', 'n', 'g']
使用分片赋值可以实现删除操作,可以删除列表中的单个元素或者删除列表中的多个连续元素
1 >>> name 2 ['lufei', 'suolong', 's', 'u', 'o', 'l', 'o', 'n', 'g'] 3 >>> name[2:]=[] 4 >>> name 5 ['lufei', 'suolong']
- 列表方法
方法是与一些对象具有紧密联系的函数。调用方法:对象.方法(参数)。对象和方法名之间需要用点号隔开。
1.append
用于在列表末尾追加新对象,该方法不是简单的返回一个新列表,而是在原有列表的位置进行修改。这种修改方法在一般需求中适用,但是某些特殊情况下会很麻烦,在学习sort时会对这种情况进行说明。
1 >>> haizei=['lufei','namei'] 2 >>> haizei.append('suolong') 3 >>> haizei 4 ['lufei', 'namei', 'suolong']
适用分片赋值也可以实现append的操作,只需要把分片的分为设置到最后一个元素即可
1 >>> haizei 2 ['lufei', 'namei', 'suolong'] 3 >>> haizei[3:]=['shanzhi'] 4 >>> haizei 5 ['lufei', 'namei', 'suolong', 'shanzhi']
原列表中有三个对象,对象的索引分别是0、1、2,现在要适用分片赋值在列表的末尾追加一个对象‘shanzhi’。分片中的第一个索引是会被改变的值,所以第一个索引应该设置为原列表中最后一个对象的索引的下一个索引序号,因为是在列表的末尾追加,第二个索引可以不设置。
假如现在要在列表的任意一位置插入对象,使用append不能够实现,但是使用分片赋值是可以实现的。现在haizei列表的2位置插入兑现‘luobin’实现方法如下代码:
1 >>> haizei 2 ['lufei', 'namei', 'suolong', 'shanzhi'] 3 >>> haizei[2:2]=['luobin'] ##注意这里在列表中任意位置插入对象时分片中的两个索引的设置 4 >>> haizei 5 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi']
2.count
统计某个元素在列表中出现的次数。返回统计出来的数字。
1 >>> haizei 2 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi'] 3 >>> haizei.count('luobin') 4 1 5 >>> haizei.count('qiaoba') 6 0
3.extand(扩展)
可以在列表的末尾一次性追加另一个列表中的多个元素。
1 >>> haizei 2 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi'] #原列表 3 >>> num=[1,2,3] #列表num 4 >>> haizei.extend(num) #用列表num扩展原列表haizei 5 >>> haizei 6 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi', 1, 2, 3] #扩展的结果是把列表num中的所有元素追加在原列表haizei的末尾 7 >>> haizei.extend(num[1:]) #用于扩展的列表是num中的部分元素,使用分片获取 8 >>> haizei 9 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi', 1, 2, 3, 2, 3] #结果
在以上代码中,对原列表进行扩展后,查看原列表内的元素可以看到,扩展是在原列表的位置上进行修改,而不是返回一个新的列表(区别于序列的通用操作中的连接操作)
1 >>> haizei 2 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi'] 3 >>> a=[1,2,3] 4 >>> haizei.extend(a) #列表的扩展方法 5 >>> haizei 6 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi', 1, 2, 3] #修改了原列表 7 8 #使用序列的通用操作连接后的结果区别于列表的扩展 9 >>> haizei 10 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi'] 11 >>> haizei+a 12 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi', 1, 2, 3] #使用连接后,返回的是一个新的列表,未对原列表修改 13 >>> haizei 14 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi'] #原列表并没有改变
从以上代码中可以看出列表extend和序列的连接操作结果的区别。为什么是这样的结果在学sort方法是学习具体分析。这里需要说明的是连接操作的结果是返回一个包含haizei列表和a列表副本的新列表,列表的extend是在原列表haizei中追加了a列表中的元素,连接操作的效率比extend方法低。
同样extend方法也可以使用分片操作来实现:
1 >>> haizei 2 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi'] 3 >>> a=[1,2,3] 4 >>> haizei[len(haizei):]=a 5 >>> haizei 6 ['lufei', 'namei', 'luobin', 'suolong', 'shanzhi', 1, 2, 3]
4.insert方法
在原列表中某个位置插入对象,方法调用时需要两个参数一个是插入对象的位置,一个是插入的对象的值。从以下代码中可以查出insert也是在原列表的位置修改列表。
1 >>> haizei 2 ['lufei', 'namei', 'suolong'] 3 >>> haizei.insert(1,'shanzhi') 4 >>> haizei 5 ['lufei', 'shanzhi', 'namei', 'suolong']
同样insert也可以使用分片赋值来实现
1 >>> haizei 2 ['lufei', 'namei', 'suolong'] 3 >>> haizei[1:1]=['shanzhi'] 4 >>> haizei 5 ['lufei', 'shanzhi', 'namei', 'suolong']
5.pop
删除列表中一个元素(默认是最后一个元素),然后返回该元素的值。pop是列表所有方法中唯一一个返回元素值的方法,同样也是在原列表上就行删除。是否可以修改删除元素的位置。
1 >>> haizei 2 ['lufei', 'shanzhi', 'namei', 'suolong'] 3 >>> haizei.pop() 4 'suolong'
5 >>> haizei
6 ['lufei', 'shanzhi', 'namei'
pop方法同样可以用分片赋值来实现:
1 >>> haizei 2 ['lufei', 'shanzhi', 'namei', 'suolong'] 3 >>> haizei[3:]=[] 4 >>> haizei 5 ['lufei', 'shanzhi', 'namei']
使用pop和append结合使用可以实现后进先出的数据结构-栈
7.remove
溢出列表中某个元素的第一个匹配项。remove是一个没有返回值的原位置修改方法。remove方法执行后不返回任何值。
1 >>> haizei 2 ['lufei', 'shanzhi', 'namei', 'qiaoba', 'luobin', 'shanzhi'] 3 >>> haizei.remove('shanzhi') 4 >>> haizei 5 ['lufei', 'namei', 'qiaoba', 'luobin', 'shanzhi']
remove不能使用分片操作来实现,因为他的参数不是列表的索引,而是列表中的元素。所有的根据列表中匀速索引对元素进行的增、删、改、查操作使用分片都是可以实现的。
8.reverse
将列表中的元素方向存放,对原列表进行修改。
1 >>> haizei 2 ['lufei', 'namei', 'qiaoba', 'luobin', 'shanzhi'] 3 >>> haizei.reverse() 4 >>> haizei 5 ['shanzhi', 'luobin', 'qiaoba', 'namei', 'lufei']
9.sort
在原位置对列表进行排序,改变原来的列表。
1 >>> num=[34,5,443,656,43,45,12,1] 2 >>> num.sort() 3 >>> num 4 [1, 5, 12, 34, 43, 45, 443, 656]
以上代码对列表num根据数字大小进行了排序。默认情况下sort函数根据Python的默认排序规则按牲畜排列元素。
10.高级排序
如果想要按照特定的方式对列表进行排序,则需要通过compare来给出排序规则。实现num的降序排序规则。
总结:
列表是Python内建的6中序列之一,序列是Python中最常见的数据结构,数据结构是按照一定的方式组织在一起的n个元素的集合。
列表可以执行的操作包含了序列的通用操作、列表的基本操作、列表的方法调用。
通用操作:索引、分片、步长、成员资格、加法、乘法、长度、最大值、最小值。
列表基本操作:list函数、赋值、删除del、分片赋值。
列表方法:append、insert、extend、pop、remove、index、reverse、sort。
在列表的所有方法中,在返回值和修改方法上对列表又有不一样的结果。
返回值:append、insert、extend、reverse、sort返回的是一个列表
pop返回的是一个元素的值
index返回的是一个元素的索引位置
是否在原列表修改:所有的方法除了index是查询操作外,都在列表的原位置修改列表。这样就对 一些特定需求的实现上产生了影响。
需求:在原列表的寄出上产生一个副本,返回修改后的副本。
1 >>> haizei 2 ['shanzhi', 'luobin', 'qiaoba', 'namei', 'lufei'] 3 >>> a=haizei 4 >>> a.sort() 5 >>> haizei 6 ['lufei', 'luobin', 'namei', 'qiaoba', 'shanzhi'] 7 >>> a 8 ['lufei', 'luobin', 'namei', 'qiaoba', 'shanzhi']
在上述代码中希望的是在保留原列表haizei不变的情况下返回经过排序后的原列表haizei的一个副本。
执行a=haizei是想创建一个haizei的副本,然后副本a调用方法sort对副本进行排序。结果却是原列表haizei和a都发生了改变。问题的关键是在创建副本时使用赋值只是把变量a的指针指向了原列表haizei的位置,并不是真正的创建了一个haizei的副本,此时a和haizei是指向同一个位置的,修改a或者是海贼本质上修改的都是同一个列表(这也说明了Python中的赋值在内存中实现的本质)。
如何创建一个列表副本?先创建一个空的列表,然后使用分片赋值将原列表的所有元素都赋值给副本列表,此时在内存中就会存在两块地址空间分别存储原列表和副本列表,这时对副本列表进行的任何操作就都和原列表没有任何关系了。
1 >>> haizei 2 ['lufei', 'luobin', 'namei', 'qiaoba', 'shanzhi'] 3 >>> b=[] #创建一个空列表作为副本列表 4 >>> b[0:]=haizei[:] #将原列表的值都赋值给副本列表 5 >>> b 6 ['lufei', 'luobin', 'namei', 'qiaoba', 'shanzhi'] 7 >>> b.reverse() #修改副本列表 8 >>> haizei 9 ['lufei', 'luobin', 'namei', 'qiaoba', 'shanzhi'] 10 >>> b 11 ['shanzhi', 'qiaoba', 'namei', 'luobin', 'lufei']