超详解——Python 列表详解——小白篇

2024-06-15 10:33:11 浏览数 (1)

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

1. 列表简介

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

示例:

代码语言:javascript复制
lst = [1, 2, 3, "Python", [5, 6]]
print(lst)  # 输出:[1, 2, 3, 'Python', [5, 6]]

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

列表的特点

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

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

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

基本切片

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

示例:

代码语言:javascript复制
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,表示连续提取元素。当步长为负数时,可以实现反向切片。

示例:

代码语言:javascript复制
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会使用默认值。省略开始索引表示从列表的起始位置开始,省略结束索引表示到列表的末尾。

示例:

代码语言:javascript复制
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() 函数创建的,用于表示切片操作。切片对象可以用于在任何支持切片的对象中应用相同的切片。

示例:

代码语言:javascript复制
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

示例:

代码语言:javascript复制
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():移除列表中的所有元素。

示例:

代码语言:javascript复制
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)  # 输出:[]

修改元素

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

示例:

代码语言:javascript复制
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 在列表中出现的次数。

示例:

代码语言:javascript复制
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():返回列表中的元素和索引。

示例:

代码语言:javascript复制
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() 方法移除元素,可以实现堆栈操作。

示例:

代码语言:javascript复制
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 实现更高效的队列操作。

示例:

代码语言:javascript复制
queue = []
queue.append(1)
queue.append(2)
queue.append(3)
print(queue)  # 输出:[1, 2, 3]

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

使用 collections.deque

代码语言:javascript复制
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() 方法实现。

代码语言:javascript复制
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() 方法实现。

代码语言:javascript复制
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() 函数可以处理各种复杂对象,包括嵌套列表、字典、集合等。

代码语言:javascript复制
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

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

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

0 人点赞