Python巩固基础02-基本数据类型之List列表类型详解
创建列表
最普通的创建列表
>>> my_l = [1, 2, 3, 'a', 'b', 'c']
>>> my_l
[1, 2, 3, 'a', 'b', 'c']
使用list()
将其他序列转换为列表
>>> s = 'hello'
>>> a = list(s)
>>> a
['h', 'e', 'l', 'l', 'o']
使用列表生成式创建列表
>>> my_l = [i for i in range(10)] # 生成一个[0, 10)的列表
>>> my_l
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> my_l = [i for i in range(10) if i % 2 == 0] # 生成一个[0, 10)间的偶数列表
>>> my_l
[0, 2, 4, 6, 8]
>>> my_l = [i if i % 2 ==0 else -1 for i in range(10)] # 生成一个[0, 10)的列表,其中偶数保持原样,奇数变为-1
>>> my_l
[0, -1, 2, -1, 4, -1, 6, -1, 8, -1]
列表切片
内容参考豌豆花下猫的文章
切片的基本用法
- 切片即为序列的截取,切片基本写法为
[i:i+n:m]
,i
为起始索引值,i+n
为终止索引值,m
为间隔,从索引i
起,以m
为间隔,截取到索引i+n
前(不包括索引i+n
的元素)的元素; - 在切片中,
i
、i+n
、m
,都可以省略,不写i
时默认从序列最左边开始,不写i+n
时默认为序列末尾,不写m
时默认为1。三者都可以为负,当索引为-1即为序列倒数第一个元素,以此类推。m
为负数时,将列表翻转,但翻转后的元素索引仍按照翻转前来使用,m
不可以为0,会报错; - 切片为从左往右截取,若索引
i
到i+n
的元素不为从左往右,则截取不到元素。
# 表示整个列表 li[:] == li[::] == li[:9] == li[0:9] == li[-9:]
>>> li[:]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> li[2:8]
[3, 4, 5, 6, 7, 8]
>>> li[2:8:2]
[3, 5, 7]
>>> li[-1:]
[9]
>>> li[-8:-3]
[2, 3, 4, 5, 6]
>>> li[-8:-3:2]
[2, 4, 6]
>>> li[:-5]
[1, 2, 3, 4]
>>> li[::-1]
[9, 8, 7, 6, 5, 4, 3, 2, 1]
# 当m间隔为-1时,可以理解为先将列表翻转(即为负号的作用),然后再按照翻转前的索引和间隔的绝对值去进行切片截取
>>> li[-2:-8:-1] # 例如[-2:-8:-1],即为将列表翻转后,从第-2个元素(8),截取到第-8个元素(2)
[8, 7, 6, 5, 4, 3]
>>> li[2:5:-1] # 若使用此写法,即为从索引为2的元素(3),间隔为1的截取到索引为5的元素(6),在翻转后的列表看来是从右往左,因此截取不到元素
[]
>>> li[:-5:-1] # 列表翻转后,从最左端截取到索引为-5的元素
[9, 8, 7, 6]
>>> li[:-5:-3] # 列表翻转后,间隔为3的从最左端截取到索引为-5的元素
[9, 6]
切片的高级用法
- 切片是返回了一个新的序列;
- 切片是浅拷贝,拷贝的是原序列中对象的引用,当拷贝出的原序列中的对象都为不可变对象时,对拷贝的序列进行赋值修改等,并不会影响原序列。但若拷贝出的原序列的对象中有可变对象,在拷贝出的序列操作此可变对象时,会影响原序列。
>>> li_1 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> li_2 = li_1[:]
>>> li_1 == li_2
True
>>> li_1 is li_2 # li_2为返回的新序列,与li_1的id内存地址并不相同
False
>>> li_2[2] = 'a'
>>> li_2
[1, 2, 'a', 4, 5, 6, 7, 8, 9]
>>> li_1
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> li_3 = [1, 2, 3, 4, 5, [9, 8, 7]]
>>> li_4 = li_3[:]
>>> li_4[5][1:] = ['a', 'b'] # 此处的 li_4[5]为拷贝出的 li_3[5]的引用,为同一个对象,因此修改后li_3也会对应变化
>>> li_4
[1, 2, 3, 4, 5, [9, 'a', 'b']]
>>> li_3
[1, 2, 3, 4, 5, [9, 'a', 'b']]
>>> li_4[5] = 3 # 若为此中方式,事实上修改的为 li_4中,索引为5的元素的引用,将索引为5的元素指向了3,因此li_3不会变化
>>> li_4
[1, 2, 3, 4, 5, 3]
>>> li_3
[1, 2, 3, 4, 5, [9, 'a', 'b']]
列表元素的增删查改
列表元素的增加
- 使用
append()
方法,在列表末尾增加元素;
>>> l = [1, 2, 3, 4]
>>> l.append(5)
>>> l.append('hello')
>>> l
[1, 2, 3, 4, 5, 'hello']
- 使用
extend()
方法,在列表后拼接另一个序列(列表、元组、字符串、字典(参数为字典时是拼接的key));
>>> l = [1, 2, 3, 4]
>>> l.extend([5, 6])
>>> l
[1, 2, 3, 4, 5, 6]
>>> l.extend('hello')
>>> l
[1, 2, 3, 4, 5, 6, 'h', 'e', 'l', 'l', 'o']
- 使用
+
操作符拼接另一个列表(只能为列表);
>>> l = [1, 2, 3]
>>> l1 = ['a', 'b']
>>> l+l1
[1, 2, 3, 'a', 'b']
- 使用
*
操作符重复列表。
>>> l = [8, 8, 6]
>>> l*3
[8, 8, 6, 8, 8, 6, 8, 8, 6]
列表元素的删除
- 使用del list[]删除列表指定索引的元素;
>>> li = ['a', 'b', 'c', 'd', 'e', 'f']
>>> del li[1]
>>> li
['a', 'c', 'd', 'e', 'f']
- 使用remove()方法删除列表指定值的元素(只删除值匹配的第一个元素);
>>> li.remove('e')
>>> li
['a', 'c', 'd', 'f']
- 使用pop()方法取出并删除列表末尾的元素;
>>> li.pop() # 会返回删除的那个元素
'f'
>>> li
['a', 'c', 'd']
- 使用pop(m)方法取出并删除列表指定索引为m的元素;
>>> li.pop(1)
'c'
- 使用clear()方法清空列表所有元素;
>>> li.clear()
>>> li
[]
- 使用del list销毁列表。
>>> del li
>>> li
Traceback (most recent call last):
File "<input>", line 1, in <module>
NameError: name 'li' is not defined
列表中元素的查找和修改,是使用列表切片和索引来进行操作,不再赘述
列表常用方法
>>> li = [1, 2, 3, 4, 5, 6]
# 统计列表中元素个数
>>> len(li)
6
# 统计列表中元素的和(需要元素皆为数字类型)
>>> sum(li)
21
# 统计列表中元素的个数
>>> li = [1, 2, 2, 3, 4, 'a', 'a']
>>> li.count(2)
2
>>> li.count('a')
2
# 统计列表中元素的最大值,需要元素为同一类型(数字类型、字符串等)
>>> lw = ['a', 'b', 'f']
>>> max(lw)
'f'
# 统计列表中元素的最小值,需要元素为同一类型(数字类型、字符串等)
>>> min(lw)
'a'
# 返回列表中某个元素的索引值,若有多个匹配则返回第一个,index(value, begin, end)接收三个参数,begin和end为索引,begin默认为0,end默认为序列长度,index在[begin, end)范围内查找value的索引
>>> li = [1, 2, 2, 3, 4, 'a', 'a']
>>> li.index('a')
5
# 翻转列表中的元素(修改的是原列表而非返回的新列表)
>>> li
[1, 2, 2, 3, 4, 'a', 'a']
>>> li.reverse()
>>> li
['a', 'a', 4, 3, 2, 2, 1]
# sort()方法排序,其中的reverse参数控制是否倒序,排序的元素都需要为同一个类型,此排序是在原列表的基础上进行,会修改原列表;sort()方法只有list有,其他序列没有此方法
>>> li = [3, 5, 1, 2, 8, 6]
>>> li.sort()
>>> li
[1, 2, 3, 5, 6, 8]
>>> li.sort(reverse=True)
>>> li
[8, 6, 5, 3, 2, 1]
# sorted()函数排序 sorted(iterable, key=None, reverse=False),其中的reverse参数控制是否倒序,排序的元素都需要为同一个类型,此排序方式返回的新列表,不修改原列表;sorted()函数可以接收任何可迭代序列
>>> li = [3, 5, 1, 2, 8, 6]
>>> sorted(li, reverse=True)
[8, 6, 5, 3, 2, 1]
>>> li
[3, 5, 1, 2, 8, 6]
# copy模块中的浅拷贝(copy()方法)和深拷贝(copy.deepcopy()方法))
# list.copy()方法,若拷贝的对象中有引用,则拷贝的是引用,若其为可变对象,该可变对象被修改后,原列表和浅拷贝列表中的可变对象都会同步变化(拷贝父对象,不会拷贝对象的内部的子对象,子对象即拷贝的引用)
# copy.deepcopy(list)方法,若拷贝的对象中有引用,则拷贝的是该引用所指向的对象值,使用该值创建的一个新的对象,与原列表再无关(完全拷贝父对象与子对象)
#
>>> import copy
>>> li = [1, 2, [3, 4], 5]
>>> li_c = li.copy()
>>> li_dc = copy.deepcopy(li)
>>> li_c
[1, 2, [3, 4], 5]
>>> li_dc
[1, 2, [3, 4], 5]
>>> li[2][1] = 9 # 同理,若li_c的可变对象有变化时,li也会被修改
>>> li
[1, 2, [3, 9], 5]
>>> li_c
[1, 2, [3, 9], 5]
>>> li_dc
[1, 2, [3, 4], 5]
参考文档
豌豆花下猫:
https://www.yuque.com/wandouhuaxiamao/pythoncat/pmz02u
https://www.yuque.com/wandouhuaxiamao/pythoncat/re6zv3#af541e61