目录

1. 列表简介

列表的特点

2. 使用切片操作符访问列表元素

基本切片

步长切片

省略索引

切片对象

3. 列表常用操作

添加元素

删除元素

修改元素

查询元素

4. 列表类型内建函数

内建函数的使用场景

5. 基于列表的堆栈和队列

堆栈

队列

堆栈和队列的实际应用

6. 列表的深拷贝和浅拷贝

浅拷贝

深拷贝

深拷贝和浅拷贝的实际应用

深拷贝和浅拷贝的区别

深拷贝的实现细节

浅拷贝和深拷贝在实际编程中的选择


Python中的列表(List)是最常用的数据结构之一,允许存储任意类型的元素,并且支持各种灵活的操作。列表是可变的,这意味着列表中的元素可以在创建后被修改。

1. 列表简介

列表是Python中的一种数据结构,用于存储有序的元素集合。列表使用方括号([])表示,元素之间用逗号分隔。列表中的元素可以是任意类型,包括其他列表。

示例:

lst = [1, 2, 3, "Python", [5, 6]]
print(lst)  # 输出:[1, 2, 3, 'Python', [5, 6]]

列表的长度可以动态变化,可以随时添加或删除元素。列表中的元素可以通过索引访问,索引从0开始。

列表的特点

  • 有序性:列表中的元素是有序排列的,每个元素都有一个唯一的索引。
  • 可变性:列表是可变的,可以随时修改其内容。
  • 混合数据类型:列表可以包含不同类型的元素,例如整数、字符串、甚至其他列表。
  • 动态调整大小:列表的大小可以动态变化,添加和删除元素非常方便。

2. 使用切片操作符访问列表元素

切片操作符([:])允许从列表中提取子列表。切片操作返回一个新的列表,不修改原列表。切片操作的基本语法是 列表[开始:结束:步长],其中 开始结束 是索引,步长 表示元素间的间隔。

基本切片

最简单的切片操作只包含开始和结束索引。

示例:

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[2:5])  # 输出:[2, 3, 4]
print(lst[:3])   # 输出:[0, 1, 2]
print(lst[7:])   # 输出:[7, 8, 9]
print(lst[:])    # 输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

步长切片

步长用于指定切片时的间隔。默认步长为1,表示连续提取元素。当步长为负数时,可以实现反向切片。

示例:

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[::2])  # 输出:[0, 2, 4, 6, 8]
print(lst[::-1]) # 输出:[9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (反转列表)

省略索引

当省略开始或结束索引时,Python会使用默认值。省略开始索引表示从列表的起始位置开始,省略结束索引表示到列表的末尾。

示例:

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
print(lst[:5])  # 输出:[0, 1, 2, 3, 4]
print(lst[5:])  # 输出:[5, 6, 7, 8, 9]
print(lst[:])   # 输出:[0, 1, 2, 3, 4, 5, 6, 7, 8, 9] (整个列表)

切片对象

切片对象是通过 slice() 函数创建的,用于表示切片操作。切片对象可以用于在任何支持切片的对象中应用相同的切片。

示例:

lst = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
slice_obj = slice(2, 5)
print(lst[slice_obj])  # 输出:[2, 3, 4]

3. 列表常用操作

Python为列表提供了丰富的操作方法,用于添加、删除、修改和查询元素。这些操作方法可以使我们高效地处理列表数据。

添加元素

  • append(x):在列表末尾添加元素 x
  • extend(iterable):扩展列表,添加多个元素。
  • insert(i, x):在指定位置 i 插入元素 x

示例:

lst = [1, 2, 3]
lst.append(4)
print(lst)  # 输出:[1, 2, 3, 4]

lst.extend([5, 6])
print(lst)  # 输出:[1, 2, 3, 4, 5, 6]

lst.insert(3, 'Python')
print(lst)  # 输出:[1, 2, 3, 'Python', 4, 5, 6]

删除元素

  • remove(x):移除列表中首次出现的元素 x
  • pop([i]):移除并返回指定位置 i 的元素,默认为最后一个元素。
  • clear():移除列表中的所有元素。

示例:

lst = [1, 2, 3, 'Python', 4, 5, 6]
lst.remove('Python')
print(lst)  # 输出:[1, 2, 3, 4, 5, 6]

lst.pop()
print(lst)  # 输出:[1, 2, 3, 4, 5]

lst.pop(2)
print(lst)  # 输出:[1, 2, 4, 5]

lst.clear()
print(lst)  # 输出:[]

修改元素

  • 通过索引直接修改元素。
  • 使用切片修改多个元素。

示例:

lst = [1, 2, 3, 4, 5]
lst[2] = 'Python'
print(lst)  # 输出:[1, 2, 'Python', 4, 5]

lst[1:4] = ['a', 'b', 'c']
print(lst)  # 输出:[1, 'a', 'b', 'c', 5]

查询元素

  • index(x[, start[, end]]):返回列表中首次出现的元素 x 的索引。
  • count(x):返回元素 x 在列表中出现的次数。

示例:

lst = [1, 2, 3, 4, 3, 5]
print(lst.index(3))  # 输出:2
print(lst.count(3))  # 输出:2

4. 列表类型内建函数

Python提供了一些内建函数,用于操作和处理列表。这些函数包括:

  • len():返回列表的长度。
  • max():返回列表中的最大值。
  • min():返回列表中的最小值。
  • sum():返回列表中所有元素的和(适用于数字列表)。
  • sorted():返回列表的排序副本。
  • reversed():返回列表的反转迭代器。
  • enumerate():返回列表中的元素和索引。

示例:

lst = [1, 2, 3, 4, 5]
print(len(lst))     # 输出:5
print(max(lst))     # 输出:5
print(min(lst))     # 输出:1
print(sum(lst))     # 输出:15
print(sorted(lst))  # 输出:[1, 2, 3, 4, 5]
print(list(reversed(lst)))  # 输出:[5, 4, 3, 2, 1]

for index, value in enumerate(lst):
    print(f"{index}: {value}")
# 输出:
# 0: 1
# 1: 2
# 2: 3
# 3: 4
# 4: 5

内建函数的使用场景

  • len() 常用于获取列表长度,以便在遍历或索引操作时进行边界检查。
  • max()min() 适用于需要找到列表中的最大和最小元素的场景,尤其在数据分析和排序操作中非常有用。
  • sum() 主要用于对数值列表进行累加操作,在统计计算中非常常见。
  • sorted() 用于获取列表的排序副本,而不修改原列表,非常适合在需要保持原数据不变的情况下进行排序。
  • reversed() 提供了一种简单的方法来反转列表中的元素顺序,尤其在需要从后向前遍历列表时非常有用。
  • enumerate() 提供了同时获取元素和索引的功能,在需要知道元素位置的遍历操作中非常方便。

5. 基于列表的堆栈和队列

列表可以用作堆栈(先进后出)和队列(先进先出)。Python提供了一些方法,可以方便地实现堆栈和队列操作。

堆栈

使用 append() 方法添加元素,使用 pop() 方法移除元素,可以实现堆栈操作。

示例:

stack = []
stack.append(1)
stack.append(2)
stack.append(3)
print(stack)  # 输出:[1, 2, 3]

stack.pop()
print(stack)  # 输出:[1, 2]

队列

使用 append() 方法添加元素,使用 pop(0) 方法移除元素,可以实现队列操作。然而,这种方法效率较低,因为每次 pop(0) 操作都需要移动所有元素。可以使collections.deque 实现更高效的队列操作。

示例:

queue = []
queue.append(1)
queue.append(2)
queue.append(3)
print(queue)  # 输出:[1, 2, 3]

queue.pop(0)
print(queue)  # 输出:[2, 3]

使用 collections.deque

from collections import deque

queue = deque([1, 2, 3])
queue.append(4)
print(queue)  # 输出:deque([1, 2, 3, 4])

queue.popleft()
print(queue)  # 输出:deque([2, 3, 4])

堆栈和队列的实际应用

  • 堆栈:堆栈的典型应用包括函数调用栈、表达式求值、括号匹配等。在实现递归算法时,堆栈结构显得尤为重要。
  • 队列:队列在广度优先搜索(BFS)、任务调度、消息队列等场景中广泛应用。使用 collections.deque 可以更高效地实现这些操作。

6. 列表的深拷贝和浅拷贝

拷贝列表时,有两种方式:浅拷贝和深拷贝。浅拷贝只复制列表中的引用,而深拷贝则复制整个列表及其包含的所有对象。

浅拷贝

浅拷贝可以通过切片操作符 [:]copy 模块的 copy() 方法实现。

import copy

lst = [1, 2, [3, 4]]
shallow_copy = lst[:]
shallow_copy2 = copy.copy(lst)

shallow_copy[2][0] = 'Python'
print(lst)          # 输出:[1, 2, ['Python', 4]]
print(shallow_copy) # 输出:[1, 2, ['Python', 4]]
print(shallow_copy2)# 输出:[1, 2, ['Python', 4]]

修改浅拷贝中的子列表会影响原列表,因为它们共享同一个子列表对象。

深拷贝

深拷贝可以通过 copy 模块的 deepcopy() 方法实现。

import copy

lst = [1, 2, [3, 4]]
deep_copy = copy.deepcopy(lst)

deep_copy[2][0] = 'Python'
print(lst)       # 输出:[1, 2, [3, 4]]
print(deep_copy) # 输出:[1, 2, ['Python', 4]]

深拷贝和浅拷贝的实际应用

  • 浅拷贝:适用于对一维列表进行复制或当列表中元素是不可变对象时(例如字符串、数字等)。
  • 深拷贝:适用于多维列表或当列表中包含可变对象(例如嵌套列表)时,确保拷贝的副本与原始列表完全独立。

深拷贝和浅拷贝的区别

  • 浅拷贝:仅复制对象的引用,不复制对象本身。如果原对象内部的子对象发生改变,浅拷贝的对象也会随之改变。
  • 深拷贝:复制对象及其所包含的所有子对象,完全独立于原对象。即使原对象内部的子对象发生改变,深拷贝的对象也不会受影响。

深拷贝的实现细节

深拷贝通过递归地复制对象及其包含的所有子对象实现。在Python中,copy.deepcopy() 函数可以处理各种复杂对象,包括嵌套列表、字典、集合等。

import copy

lst = [1, 2, {'a': [3, 4], 'b': 5}]
deep_copy = copy.deepcopy(lst)

deep_copy[2]['a'][0] = 'Python'
print(lst)       # 输出:[1, 2, {'a': [3, 4], 'b': 5}]
print(deep_copy) # 输出:[1, 2, {'a': ['Python', 4], 'b': 5}]

deep_copy 完全独立于 lst,修改 deep_copy 中的元素不会影响原列表 lst

浅拷贝和深拷贝在实际编程中的选择

在编写程序时,选择浅拷贝还是深拷贝取决于具体需求。如果只是需要复制一维列表或包含不可变对象的列表,浅拷贝即可满足需求,并且效率较高。然而,当需要复制多维列表或包含可变对象的复杂结构时,深拷贝是更好的选择,因为它能够确保原列表与副本完全独立,避免意外修改带来的问题。

Logo

助力广东及东莞地区开发者,代码托管、在线学习与竞赛、技术交流与分享、资源共享、职业发展,成为松山湖开发者首选的工作与学习平台

更多推荐