1 数据结构简介

定义和使用列表

如果一个学生有多种爱好,比如游泳、健身、跑步等,我们要如何在代码中在描述它呢?在 Python 中,我们可以使用列表来描述它,列表是由一系列元素按特定顺序构成的数据序列,通常使用[]字面量语法来定义列表,列表中的多个元素用逗号进行分隔,并且元素是可以重复的,代码如下所示

hobbies = ['swim', 'fitness','running'] # 游泳、健身、跑步
print(hobbies)  # ['swim', 'fitness','running']

使用列表生成式创建列表

列表生成式是一种快速创建列表的方法。它的基本语法如下:

[expression for item in iterable]
# 将 1-10 的平方放入一个列表中
squares = [x ** 2 for x in range(1, 11)] 
print(squares) # 输出结果为 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

除了基本语法之外,列表生成式还支持添加条件判断,用于过滤元素。语法如下:

[expression for item in iterable if condition]
# 将 1-10 中的偶数放入一个列表中
numbers = [x for x in range(1, 11) if x % 2 == 0]
print(numbers) # 输出结果为 [2, 4, 6, 8, 10]

使用 list 构造器创建列表

除此以外,还可以通过 Python 内置的 list 函数将其他序列变成列表。准确的说,list并不是一个普通的函数,它是创建列表对象的构造器函数,它可以接受一个可迭代对象作为可选参数,例如元组、字符串、集合等

hobbies = list() # 创建一个空列表
hobbies2 = [] # 创建一个空列表
print(hobbies) # []
print(hobbies2) # []

也可以为 list 传入字符串,来创建一个字符列表:

hello = list('hello') # 创建一个字符列表
print(hello) # ['h', 'e', 'l', 'l', 'o']

还可以传入一个 range 函数生成的序列,来创建一个数字列表:

hello = list(range(0, 10)) # 创建一个数字列表
print(hello) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

列表的索引

列表跟字符串一样,其中的元素可以通过索引来访问,索引是整数值,从 0 开始,表示列表中的第一个元素。对列表做索引操作一定要注意索引越界的问题,对于有 N 个元素的列表,正向索引的范围是 0 到 N-1,负向索引的范围是-1-N,如果超出这个范围,将引发IndexError异常,错误信息为:list index out of range

hobbies = ['swim', 'fitness','running']
print(hobbies[0])    # 'swim'
print(hobbies[2])    # 'running'
print(hobbies[3])    # 这样会报错 list index out of range

由于列表是可变类型,所以通过索引操作既可以获取列表中的元素,也可以更新列表中的元素。举例如下:

hobbies = ['swim', 'fitness','running']
hobbies[0] = 'study'
print(hobbies)    # ['study', 'fitness', 'running']

列表的拼接

items1 = [35, 12, 99, 68, 55, 87]
items2 = [45, 8, 29]

# 列表的拼接,可以直接使用加法运算符,会将 item2 的列表元素追加到 item1 之后
items3 = items1 + items2
print(items3)    # [35, 12, 99, 68, 55, 87, 45, 8, 29]

列表的切片

可以使用切片来获取列表中的一部分元素。切片的语法是 my_list[start:end],其中 start 表示切片起始位置,end 表示切片结束位置(但不包含该位置的元素)。例如,my_list[1:3]将返回列表中的第二个和第三个元素。注意,列表切片会返回一个全新的列表,不会对原列表做出任何改变。

items1 = [35, 12, 99, 68, 55, 87]

# 列表的切片
print(items1[:5]) #[35, 12, 99, 68, 55]
print(items1[4:]) #[55, 87]

获取列表长度

可以使用 len 函数来获取长度:

# 获取列表的长度(元素个数)
items = ['Python', 'Java', 'Go', 'Kotlin']
size = len(items)
print(size) #4

判断某个元素是否在列表内

可以使用 in 关键字来做判断

print('Python' in ['Python', 'Java', 'Go', 'Kotlin']) # True
print('JS' in ['Python', 'Java', 'Go', 'Kotlin']) # False

列表的方法

添加元素

items = ['Python', 'Java', 'Go', 'Kotlin']
# 使用 append 方法在列表尾部添加元素
items.append('Swift')
print(items)    # ['Python', 'Java', 'Go', 'Kotlin', 'Swift']
# 使用 insert 方法在列表指定索引位置插入元素,注意索引是从 0 开始。
items.insert(2, 'SQL')
print(items)    # ['Python', 'Java', 'SQL', 'Go', 'Kotlin', 'Swift']

删除元素

# 删除指定内容的元素
items = ['Python', 'Java', 'Go', 'Kotlin', 'Swift']
items.remove('Java')
print(items)    # ['Python',  'Go', 'Kotlin', 'Swift']

# 删除列表尾部的元素,并将删除的值返回
last_element = items.pop()
print(last_element)   #Swift
print(items)   #['Python', 'Go', 'Kotlin']

# 删除指定索引位置的元素
items.pop(0)
print(items)	#['Go', 'Kotlin']

# 清空列表中的元素
items.clear()
print(items)    # []

在使用remove方法删除元素时,如果要删除的元素并不在列表中,会引发ValueError异常,错误消息是:list.remove(x): x not in list。在使用pop方法删除元素时,如果索引的值超出了范围,会引发IndexError异常,错误消息是:pop index out of range

更新元素

items = ['Python', 'Java', 'Go', 'Kotlin', 'Swift']
items[0] = 'JS' # 更新索引 0 位置上的元素
print(items)	#['JS', 'Java', 'Go', 'Kotlin', 'Swift']

items[1:3] = ['Node', 'Browser'] # 一次性更新多个位置上的元素
print(items)	#['JS', 'Node', 'Browser', 'Kotlin', 'Swift']

查找元素在列表中的索引

列表的 index 方法用于查找某个元素在列表中第一次出现的位置,如果该元素不存在于列表中,则会抛出 ValueError 异常。语法如下:index(element[, start[, end]]),其中 element 是要查找的元素,start 和 end 是可选参数,用于指定查找的起始和结束位置。如果指定了 start,那么查找将从该位置开始;如果指定了 end,那么查找将在该位置结束(但不包括该位置)。

items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']

# 查找元素的索引位置
print(items.index('Python'))       # 0
print(items.index('Python', 2))    # 5
print(items.index('Java', 3))      # 这一行会报错,起始位置已跳过要查找的元素

查找元素在列表中出现的次数

列表类型的 count 方法用来统计一个元素在列表中出现的次数。

items = ['Python', 'Java', 'Java', 'Go', 'Kotlin', 'Python']

# 查找元素出现的次数
print(items.count('Python'))    # 2
print(items.count('Go'))        # 1
print(items.count('Swfit'))     # 0

元素排序

列表的 sort 操作可以实现列表元素的就地排序,语法如下:

list.sort(key=None, reverse=False)

其中,key 和 reverse 都是可选参数。key 是一个函数,用于指定排序的关键字(默认为 None),一般用在列表的元素为符合类型,比如元素还是一个列表,或者是后续学的字典等等;reverse 是一个布尔值,用于指定排序的顺序(默认为 False,即升序)。

items = ['Python', 'Java', 'Go', 'Kotlin', 'Python']

# 升序排序
items.sort()
print(items)    # ['Go', 'Java', 'Kotlin', 'Python', 'Python']

# 降序排序
items.sort(reverse=True)
print(items) # ['Python', 'Python', 'Kotlin', 'Java', 'Go']

元素反转

reverse 操作可以实现元素的反转,代码如下所示:

items = ['Python', 'Java', 'Go', 'Kotlin', 'Python']

# 反转
items.reverse()
print(items)    # ['Python', 'Kotlin', 'Go', 'Java', 'Python']

注意sort() 和 reverse() 方法都会直接对原列表做出改变。