这篇文章将会介绍在 Python 中最经常使用的一种序列类型:列表
1、创建列表
列表的字面量是 []
,它对应的内置函数是 list()
,这两种方式均可以用于创建列表
>>> # 使用字面量去创建一个空列表 >>> li = [] >>> # 使用内置函数创建一个空列表 >>> li = list() >>> # 使用内置函数将其他序列类型转化为列表类型 >>> li = list((1, 2, 3))
列表中可以存放各种类型的元素,包括 int
、float
等基本类型,也包括 dict
、str
等标准类型
>>> li = [27, 3.7, {'Python': 'Beautiful'}, 'Hello', (0, 2), [0, 3]] >>> type(li) # <class 'list'>
2、添加元素
append()
:将单个元素添加到列表末尾extend()
:将一个新列表拓展到原列表末尾insert()
:将单个元素插入到列表指定位置
>>> li = ['one'] # li: ['one'] >>> li.append('two') # li: ['one', 'two'] >>> li.extend(['three','five']) # li: ['one', 'two', 'three', 'five'] >>> li.insert(3, 'four') # li: ['one', 'two', 'three', 'four', 'five']
3、删除元素
pop()
:删除并返回列表的最后一个元素,也可以通过参数指定待删除元素的索引remove()
:删除第一个能匹配参数值的元素,不返回内容clear()
:清空整个列表,不返回内容
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> lastVal = li.pop() # li: ['one', 'two', 'three', 'four'] >>> firstVal = li.pop(0) # li: ['two', 'three', 'four'] >>> li.remove('three') # li: ['two', 'four'] >>> li.clear() # li: []
4、列表索引
通过索引,可以访问在指定位置的元素,也能修改在指定位置的元素
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> # 访问在指定位置的元素 >>> li[0] # 'one' >>> # 修改在指定位置的元素 >>> li[0] = 'new' >>> # 访问在指定位置的元素 >>> li[0] # 'new'
5、列表切片
(1)基本使用
除了能通过索引访问单个元素外,还可以使用切片访问指定范围的元素简单来说,切片使用两个索引指定范围,这两个索引被称为起始索引和结束索引切片的范围包括起始索引指定的元素,但不包括结束索引指定的元素,它是一个半闭半开的区间
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li[1:3] # ['two', 'three']
(2)默认索引
当未指定起始索引时,默认为 0;当未指定结束索引时,默认为 列表长度
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li[:4] # 未指定起始索引,默认为 0 # ['one', 'two', 'three', 'four'] >>> li[1:] # 未指定结束索引,默认为 列表长度 # ['two', 'three', 'four', 'five']
当前后索引都省略时,意味着创建一份原列表的副本
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li[:] # ['one', 'two', 'three', 'four', 'five']
这里需要注意,切片是原列表的一份副本,操作切片并不会对原列表产生影响
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li_slice = li[:] >>> li_slice.append('six') >>> li_slice # ['one', 'two', 'three', 'four', 'five', 'six'] >>> li # ['one', 'two', 'three', 'four', 'five']
(3)负数索引
除了支持使用正整数进行索引外,还支持使用负整数进行索引,即可以从后往前开始计数
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li[-1] # 'five' >>> li[1:-1] # ['two', 'three', 'four']
(4)设置步长
上面操作都是对列表中连续的元素进行操作的,有没有一种可能允许我们跳跃性的选取元素呢答案是肯定的,这时就要用到切片操作中的第三个参数用于指定步长,若没有指定,则默认为 1
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li[::2] # ['one', 'three', 'five']
利用步长的设置,我们可以很简单地做一些有趣的操作,例如反转列表
>>> li = ['one', 'two', 'three', 'four', 'five'] >>> li[::-1] # ['five', 'four', 'three', 'two', 'one']
6、列表操作符
列表操作符允许将原本用于基本数据类型的算术运算符用到列表上,但其含义可能有所不同
(1)连接操作符 ( +
):将两个列表连接起来
>>> ['one', 'two'] + [ 'three', 'four'] # ['one', 'two', 'three', 'four']
(2)重复操作符 ( *
):将列表中的元素重复指定次
>>> ['one', 'two'] * 2 # ['one', 'two', 'one', 'two']
通过重复操作符,我们可以很轻松地初始化一个具有相同元素的列表
>>> [0] * 10 # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
(3)成员资格操作符 ( in
、not in
):判断一个值是否属于该列表
>>> 'one' in ['one', 'two'] # True
7、列表方法
(1)count()
:统计指定值在列表中出现的次数
>>> li = [1, 5, 9, 3, 5, 7, 2, 5, 8] >>> li.count(5) # 3
(2)index()
:查找指定值在列表中第一次出现的索引
>>> li = [1, 5, 9, 3, 5, 7, 2, 5, 8] >>> li.index(5) # 1
(3)reverse()
:按相反的顺序排列列表中的元素(对原列表进行操作,不返回值)
>>> li = [1, 2, 3, 4, 5] >>> li.reverse() >>> li # [5, 4, 3, 2, 1]
(4)sort()
:对列表进行排序(对原列表进行操作,不返回值)
>>> li = [1, 5, 2, 4, 3] >>> li.sort() >>> li # [1, 2, 3, 4, 5]
sort()
方法不返回任何值,如果想要返回排序后的列表,可以使用 sorted()
方法
事实上, sorted()
方法可以应用于任何序列,但总是返回一个列表
>>> li = [1, 5, 2, 4, 3] >>> sorted_li = sorted(li) >>> sorted_li # [1, 2, 3, 4, 5]
sort()
方法还可以接受两个可选的参数,分别为 key
和 reverse
key
可以指定排序目标,一般在列表元素为复杂对象时使用
>>> li = [{ 'fruit': 'apple', 'price': 123 }, { 'fruit': 'banana', 'price': 321 }, { 'fruit': 'orange', 'price': 213 }] >>> li.sort(key = lambda item: item['price']) >>> li # [{'fruit': 'apple', 'price': 123}, {'fruit': 'orange', 'price': 213}, {'fruit': 'banana', 'price': 321}]
reverse
是布尔类型的参数,默认为False
,表示顺序排列,如果为True
,表示反序排列
>>> li = [1, 5, 2, 4, 3] >>> li.sort(reverse = True) >>> li # [5, 4, 3, 2, 1]
8、高级技巧
(1)列表迭代
- 迭代列表中的元素值
>>> li = ['A', 'B', 'C'] >>> for item in li: print(item) # A # B # C
- 同时迭代列表中的索引值和元素值
>>> li = ['A', 'B', 'C'] >>> for index, value in enumerate(li): print(index, value) # 0 A # 1 B # 2 C
- 同时迭代两个列表
>>> name = ['Alice', 'Bob', 'Cathy'] >>> grade = [85, 98, 95] >>> for i, j in zip(name, grade): print(i, j) # Alice 85 # Bob 98 # Cathy 95
(2)列表推导式
列表推导式提供了一种创建列表的简便方法,其基本格式如下:
new_list = [expression(i) for i in old_list if condition(i)]
翻译成一般语句就是:
new_list = [] for i in old_list: if condition(i): new_list.append(expression(i))
① 处理元素:例如对每一个元素取幂
>>> old_list = list(range(10)) >>> new_list = [i**2 for i in old_list] >>> new_list # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
② 过滤元素:例如过滤奇数元素
>>> old_list = list(range(10)) >>> new_list = [i for i in old_list if i % 2 == 0] >>> new_list # [0, 2, 4, 6, 8]
③ 矩阵转置:解决这个问题比较复杂,我们需要用到嵌套的列表推导式
列表推导式的嵌套格式如下:
new_list = [expression(i, j) for i in old_list_one for j in old_list_two]
翻译成一般语句就是:
new_list = [] for i in old_list_one: for j in old_list_two: new_list.append(expression(i, j))
列表推导式的嵌套格式变体如下:
new_list = [[expression(i, j) for i in old_list_one] for j in old_list_two]
翻译成一般语句就是:
new_list = [] for i in old_list_one: temp = [] for j in old_list_two: temp.append(expression(i, j)) new_list.append(temp)
解决矩阵转置:
>>> old = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] >>> new = [[row[i] for row in old] for i in range(len(old))] >>> new # [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
9、元组
讲了这么多,终于把列表部分的知识点讲完了,接下来简单补充一下元组的相关知识点
元组和列表很相似,它们主要有以下的不同:
- 在本质上,列表是可变的,元组是不可变的(不能直接修改元组元素内容),这是它们最大的区别
- 在使用上,除了创建方法,以及某些会直接修改元组元素内容的操作不能使用,其他都和列表一致
由于创建元组的方法比较特殊,下面主要讲一下元组的创建方法和一些注意点
与列表相对应,元组的字面量是 ()
,它对应的内置函数是 tuple()
,这两种方式都能创建元组
>>> # 使用字面量去创建一个空元组 >>> tup = () >>> # 使用内置函数创建一个空元组 >>> tup = tuple() >>> # 使用内置函数将其他序列类型转化为元组类型 >>> tup = tuple([1, 2, 3])
但可能与想象中的有所不同,创建带有一个元素的元组不能使用下面的语法
>>> tup = (1) >>> type(tup) # <class 'int'>
事实上,元组的字面量是 ()
,这句话从某种层面上来说是不准确的
因为创建带有一个元素的元组时,不能使用上面的语法,而创建带有多个元素的元组时,也可以不使用 ()
>>> tup = 1, >>> type(tup) # <class 'tuple'> >>> tup = 1, 2, 3 >>> type(tup) # <class 'tuple'>
文章知识点与官方知识档案匹配,可进一步学习相关知识