在介绍数据类型前,我们先介绍一个概念--序列。序列是 Python 中最基本的数据结构。序列中的每个值都有对应的位置值,即索引,通过索引我们可以访问指定位置的元素。
上一篇我们介绍的字符串也是一种序列类型,我们可通过索引访问指定字符,比如 s = 'hello world!',s[1] = 'e'。
本篇我们介绍 Python 中一种非常常用的序列数据类型--列表。
本文主要从以下几方面来介绍:
1 列表的基本概念
2 列表的基本操作
第一部分:列表的基本概念
列表是 Python 中的一种容器序列类型。首先列表是一个序列,我们可以通过索引访问指定的元素,而称之为是容器,是因为列表可以存储各种类型的数据,比如字符串、数字、列表等等。
列表也是一个可变序列,可以对列表中的元素进行增删改查。
列表中的元素以逗号 , 分隔,用 [] 将元素括起来。
创建列表或生成列表有多种方法:根据列表定义创建:元素以逗号分隔,并用 [ ] 括起来,如 [1, 'a', True],是最简单的一种方法。
创建空列表:[ ]。
list() 创建:根据其他类型数据创建列表,如 list('hello'),list(range(10))。
创建一个空列表:list()。
列表生成式:如 [x**2 for x in range(10)]。
第二部分:列表的基本操作
下面介绍一些列表常用的操作:
1 索引与切片操作
2 添加元素
3 删除元素
4 列表排序
5 反转列表
6 列表统计
7 成员关系判断
8 列表转换
1 索引与切片操作
由于列表是一个序列,列表中的每个元素都有特定的位置,即索引,因此我们就可以根据元素的索引来访问元素。
1.1 根据单个索引访问列表中的值
列表的索引从 0 开始,索引取值的范围为 -len(list) 到 len(list)-1(list表示列表),超过这个范围访问列表则抛出 IndexError。索引 -1 表示列表的最后一个元素位置,-2 为倒数第二个元素位置,以此类推。
l = [1, 2, 3, 'a', 'b', 'c']
r1 = l[2]
r2 = l[-1]
print(r1, r2)
# 输出
3 'c'
1.2 列表切片取值
列表 seq 切片格式为:seq[start:end:step],左闭右开,start:起始索引,从0开始;end:结束索引,step:步长,默认为1,步长为正值从左往右取值,为负值从右往左取值。
在实际列表切片取值时,索引设置主要有以下几种情况:
同时有起止索引:
l = [1, 2, 3, 4, 5]
r1 = l[1:3]
r2 = l[1:4:3]
#修改步长为3
print("r1={}, r2={}".format(r1,r2))
# 输出
r1=[2, 3], r2=[2]
仅有开始索引:
l = [1, 2, 3, 4, 5]
r1 = l[1:]
r2 = l[-2:]
# 开始索引为负值
print("r1={}, r2={}".format(r1,r2))
# 输出
r1=[2, 3, 4, 5], r2=[4, 5]
仅有结束索引:
l = [1, 2, 3, 4, 5]
r1 = l[:3]
r2 = l[:-1]
# -1表示最后索引
print("r1={}, r2={}".format(r1,r2))
# 输出
r1=[1, 2, 3], r2=[1, 2, 3, 4]
无开始结束索引:
r1 = l[::] # 全选 l[:]
r2 = l[::2]
print("r1={}, r2={}".format(r1,r2))
# 输出
r1=[1, 2, 3, 4, 5], r2=[1, 3, 5]
逆向索引:
r1 = l[-1:-4:-1]
r2 = l[-4:-1:-1]
r3 = l[::-1]
# 列表反转
print("r1={}, r2={}, r3={}".format(r1,r2,r3))
# 输出
r1=[5, 4, 3], r2=[], r3=[5, 4, 3, 2, 1]
1.3 列表切片赋值由于列表是可变序列,可以对列表的元素进行修改或删除操作。对于切片赋值,右侧必须是一个可迭代对象。对单个元素进行修改,赋值运算符右侧可以是数字,也可以是可迭代对象。
l = ['a', 'b', 'c', 'd', 'e']
l[0] = 1
l[1] = [1, 2]
print(l)
# 输出
[1, [1, 2], 'c', 'd', 'e']
切片赋值,在步长为1时,右侧可迭代对象元素个数不必与左侧切片长度相同。
l = list("abcde")
l[1:2] = ['A', 'B', 'C']
print(l)
# 输出
['a', 'A', 'B', 'C', 'c', 'd', 'e']
在步长不为1时,右侧可迭代对象元素个数必须与左侧切片长度相同,否则报错。
l = list("abcde")
l[1:2:2] = ['A', 'B', 'C']
# 报错
不替换元素,直接在相应位置插入。
l = list("abcde")
l[0:0] = [1, 2]
# 在最开始位置插入
l[3:3] = [3, 4]
# 在中间位置插入
l[10:10] = [5, 6]
# 在最后位置插入,索引要大于最后一个索引
print(l)
# 输出
[1, 2, 'a', 3, 4, 'b', 'c', 'd', 'e', 5, 6]
删除元素
l = list("abcde")
l[2:] = []
print(l)
# 输出
['a', 'b']
2 添加元素
列表添加元素主要有以下几类场景。
2.1 append
append() 方法用于在列表末尾添加新的对象,并且一次只能添加一个。append() 方法会修改原来的列表。
l = [1, 2, 'a', 'b']
print(id(l))
l.append(3)
l.append('c')
l.append(['d','e'])
print(id(l))
print(l)
# 输出
1793248533056
1793248533056
[1, 2, 'a', 'b', 3, 'c', ['d', 'e']]
从执行结果可以看到添加元素前后列表的内存地址未发生变化,这也是为什么说列表是可变数据类型,直接修改原列表而不会创建一个新的对象。
2.2 insert
insert() 方法将指定对象插入列表中指定位置。
"""语法:list.insert(index, obj)参数:obj为要插入列表中的对象,index为对象obj需要插入的索引位置。返回值:无返回值,直接在列表指定位置插入对象。"""
l = [ 1, 2, 3, 4, 5]
l.insert( 3, [ 'a', 'b'])
print(l)
# 输出
[ 1, 2, 3, [ 'a', 'b'], 4, 5]
2.3 extend
extend() 用于在列表末尾一次性追加另一个序列中的多个元素。
"""语法:list.extend(seq)参数:seq可以为列表、元组、集合、字典等,若为字典,则仅会将键(key)作为元素依次添加至原列表的末尾。"""
l = [ 1, 2, 3]
s = [ 'a', 'b']
l.extend(s)
print(l)
# 输出
[ 1, 2, 3, 'a', 'b']
2.4 用 + 实现向列表中添加另一个列表中的元素
+ 运算符可以对两个列表进行连接,不改变原列表,返回一个新的列表。
l = [1, 2, 3]
s = ['a', 'b', 'c']
r = l + s
print("l={}, r={}".format(l,r))
# 输出
l=[1, 2, 3], r=[1, 2, 3, 'a', 'b', 'c']
+= 运算符,会在原列表上进行添加另一个列表的元素,+= 操作符会自动调用 extend 方法进行合并运算。
l = [1, 2, 3]
print(id(l)) # 获取对象的内存地址
s = ['a', 'b', 'c']
l += s # 合并后对象的内存地址
print(id(l))
print(l)
# 输出
2355940909512 # 添加列表元素后内存地址不变
2355940909512
[1, 2, 3, 'a', 'b', 'c']
3 删除元素
删除操作的方法有四种:remove,pop,del,clear
3.1 remove
remove() 方法删除列表中的元素,如果要删除的元素出现多次,则只删除第一次。
"""语法:list.remove(obj)参数:obj为列表要移除的对象返回值:无返回值,直接对原列表进行修改。"""
l = [1, 'a', 2, 'a', 3, 'b']
l.remove('a')
print(f"l={l}")
# 输出
l=[1, 2, 'a', 3, 'b']
3.2 pop
pop() 方法用于删除指定位置处的元素,若不带参数则默认最后一个元素,若设置参数则删除指定索引处的元素。
"""语法:list.pop(index=-1)参数:index为可选参数,要移除元素的索引值,默认为-1。返回值:返回从列表中移除的元素对象。"""
l = [1, 2, ['a', 'b'], 3]
r1 = l.pop(2)
r2 = l.pop()
print(f"r1={r1}, r2={r2}, l={l}")
# 输出
r1=['a', 'b'], r2=3, l=[1, 2]
pop 与 append 是python中数据结构的出栈与入栈。
3.3 del
del() 方法是根据索引来删除单个元素或指定范围内的元素。
删除单个元素:
l = [1, 2, 3, 4, 5]
del l[-1]
print(l)
# 输出
[1, 2, 3, 4]
删除指定范围内的元素:
l = [1, 2, 3, 4, 5]
del l[2:]
print(l)
# 输出
[1, 2]
删除整个对象:
l = [1, 2, 3, 4, 5]
del l
print(l)
# 输出
NameError: name 'l' is not defined
此外,我们应注意 del 方法是删除引用(变量),而不是删除对象(数据),对象由自动垃圾回收机制(GC)删除。
l = [1, 2, 3, 4, 5]
s = l
del l
print(s)
# 输出
[1, 2, 3, 4, 5]
3.4 clear
clear() 方法用于清空列表中所有元素,类似于del list[:]。
"""语法:list.clear()"""
l = [1, 2, 3, 4, 5]
l.clear()
print(l)
# 输出
[]
4 列表排序
实现列表排序有两种方法:sort,sorted。
4.1 sort
sort() 方法是直接对原列表进行排序。语法:list.sort(key=None, reverse=False)
参数:key 为用来进行比较的元素,可以用内置函数或自定义函数的返回值来进行比较,函数参数只有一个。key 默认为 None。reverse 为排序规则,reverse=True 降序,reverse=False 升序,默认为升序。
返回值:没有返回值,会直接对原列表进行排序。
首先,我们先看一个最简单的排序,不设置key参数。
l1 = [1, 5, 4, 2, 3]
l2 = ['Google', 'Baidu', 'Taobao', 'Tencent', 'Douyin']
l1.sort() # 默认升序排序
l2.sort(reverse=True) # 首先比较首字符,首字符相同,比较第二个字符,以此类推。
print(f"l1={l1}\nl2={l2}")
# 输出
l1=[1, 2, 3, 4, 5]
l2=['Tencent', 'Taobao', 'Google', 'Douyin', 'Baidu']
下面,再介绍几种设置参数 key 进行排序的情况。
设置参数key,按字符串长度排序:
l = ['Google', 'Baidu', 'Taobao', 'Tencent', 'Douyin']
l.sort(key=len) # 先按字符串长度排序,再按字母排序
print(l)
# 输出
['Baidu', 'Google', 'Taobao', 'Douyin', 'Tencent']
列表元素为元组,按元组中的部分元素进行排序:
l = [(1, 'b', 'A'), (3, 'b', 'D'), (2, 'c', 'B'), (4, 'd', 'C')]
l.sort(key=lambda x: (x[0], x[2]))
print(l)
# 输出
[(1, 'b', 'A'), (2, 'c', 'B'), (3, 'b', 'D'), (4, 'd', 'C')]
列表元素为字典,按字典键或值排序:
l1 = [{'A': 1}, {'C':3}, {'B':2}]
l2 = [{'name': 'Tom', 'age': 19}, {"name": 'Jhon', 'age': 18}]
l1.sort(key=lambda x: list(x.keys()))
l2.sort(key=lambda x: x['age'])
print(f"l1={l1}\nl2={l2}")
# 输出
l1=[{'A': 1}, {'B': 2}, {'C': 3}]
l2=[{'name': 'Jhon', 'age': 18}, {'name': 'Tom', 'age': 19}]
4.2 sorted
sorted() 方法并不是列表内置的方法,可适用于所有可迭代对象的排序,返回排序后的新对象,原对象保持不变。语法:sorted(iterable, key=None, reverse=False)
参数:key为设置的排序方法,或指定迭代对象中用于排序的元素,reverse为排序规则。
返回值:返回排序后的新对象。
下面通过几个实例具体介绍 sorted() 的方法。
一维列表、元组、字典的排序:
l = [3, 1, 2, 5, 4] # 列表
t = ('c', 'a', 'e', 'b', 'd') # 元组
d = {'huawei': 1, 'vivo': 3, 'meizu': 4, 'oppo': 2} # 字典
rl = sorted(l, reverse=True)
rt = sorted(t)
rd1 = sorted(d) # 按键排序
rd2 = sorted(d.items(), key=lambda x: x[1]) # 按值排序
print(f"rl={rl}")
print(f"rl={rt}")
print(f"rl={rd1}")
print(f"rl={rd2}")
# 输出
rl=[5, 4, 3, 2, 1]
rt=['a', 'b', 'c', 'd', 'e']
rd1=['huawei', 'meizu', 'oppo', 'vivo']
rd2=[('huawei', 1), ('oppo', 2), ('vivo', 3), ('meizu', 4)]
由列表作为元素组成的列表或元组:
l = [[1, 4, 6], [3, 2, 5], [2, 3, 6], [4, 1, 3]]
r = sorted(l, key=lambda x: x[1], reverse=True)
print(r)
# 输出
[[1, 4, 6], [2, 3, 6], [3, 2, 5], [4, 1, 3]]
字典组成的列表:
l = [{'A': 1}, {'C':3}, {'B':2}]
r = sorted(l, key=lambda x: list(x.values()))
print(r)
# 输出
[{'A': 1}, {'B': 2}, {'C': 3}]
5 反转列表
在 Python 中实现列表反转有三种方式:reverse,reversed,使用列表切片。
reverse 和 reversed 可以与排序的两种方法类比,reverse 是列表的内置方法,而 reversed 适用于所有可迭代对象。
5.1 reverse
reverse() 方法用于用于反向列表中的元素。
"""语法:list.reverse()参数:无参数返回值:没有返回值,直接对原列表进行反向操作。"""
l = [1, 2, 3, 4, 5]
l.reverse()
print(l)
# 输出
[5, 4, 3, 2, 1]
5.2 reversed
"""语法:reversed(seq)参数:seq为要转换的序列,如列表、元组、字符串等。返回值:返回一个迭代器,需要通过遍历或list等类型转换获取反转后的序列。"""
s = 'AABBCC'
t = ['a', 'b', 'c']
r1 = reversed(s)
r2 = reversed(t)
print("r1={}, r2={}".format(''.join(r1), list(r2)))
# 输出
r1=CCBBAA, r2=['c', 'b', 'a']
5.3 使用列表切片实现反转
l = [1, 2, 3, 4, 5]
r = l[::-1]
print(r)
# 输出
[5, 4, 3, 2, 1]
6 列表统计
6.1 计算最大值与最小值
"""返回列表元素中的最大值/最小值。语法:max(list) / min(list)返回值:列表元素中的最大值/最小值。"""
l = [1, 2, 3, 4, 5]
r_min = min(l)
r_max = max(l)
print("最大值:{}, 最小值:{}".format(r_max, r_min))
# 输出
最大值:5, 最小值:1
6.2 计算列表元素个数
"""计算列表元素个数。语法:len(list)返回值:列表元素个数。"""
l = [1, 2, 3, 4, 5]
r = len(l)
print(r)
# 输出
5
6.3 统计元素出现次数
"""用于统计某个元素在列表中出现的次数。语法:list.count(obj)参数:obj为要统计的元素返回值:返回元素在列表中出现的次数。"""
l = ['a', 'b', 'a', 'c', 'd']
r = l.count('a')
print(r)
# 输出
2
7 成员关系判断
在 Python 中,可以使用 in 判断子对象在列表中是否存在。not in 是判断不存在。
s = 'huawei'
l = ['huawei', 'meizu', 'vivo', 'iphone']
print(s in l)
print(s not in l)
# 输出
True
False
7 列表转换
使用 list() 方法将其他类型的数据转换为列表。
s = "Hello World."
l = list(s)
print(l)
# 输出
['H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', '.']
在本篇文中介绍了列表的基本概念和常用操作,列表还有其他进阶知识,如深浅拷贝、列表解析等等,在后面文章中介绍。
—END—