0Pricing
DSA Interview Prep · 课时

列表、元组与切片

通过经典编程题中的实践示例,掌握 Python 列表操作、切片语法和元组不可变性。

列表、元组与切片 是 CoddyKit 上的免费 DSA Interview Prep 课时。 这是第 1 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 DSA Interview Prep 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 DSA Interview Prep 课程共包含 4 节课。

Python 列表:动态数组

Python 的列表是一种可以存放任意内容并自动扩展的动态数组。它有序且可变,还能通过索引即时进行 O(1) 访问。代码展示了基本用法。

nums = [3, 1, 4, 1, 5]
print(nums[0])   # 3
print(nums[-1])  # 5  (last element)
nums.append(9)
print(len(nums)) # 6

常见的列表操作

请牢记这些操作:在末尾使用 append 和 pop 的复杂度是 O(1),但在开头使用 insert 的复杂度是 O(n)。请避免在紧密循环中使用 remove,因为它每次都会重新扫描列表。

stack = []
stack.append(1)
stack.append(2)
stack.append(3)
print(stack.pop())   # 3  O(1)
print(stack)         # [1, 2]

# insert at index 0 is O(n)
stack.insert(0, 0)
print(stack)         # [0, 1, 2]

切片语法详解

切片的写法是 lst[start:stop:step],并且会在 stop 之前停止。一个经典技巧是:步长为 -1 可以在不改变原列表的情况下将列表反转。代码会逐一演示每种写法。

a = [0, 1, 2, 3, 4, 5]
print(a[1:4])    # [1, 2, 3]
print(a[:3])     # [0, 1, 2]
print(a[3:])     # [3, 4, 5]
print(a[::2])    # [0, 2, 4]  every other
print(a[::-1])   # [5, 4, 3, 2, 1, 0]  reversed

切片会创建浅拷贝

有一个实用但容易踩坑的地方:切片总会创建一个新列表,因此修改切片不会影响原列表。但它是浅拷贝,所以其中的嵌套列表仍然是共享的。请务必注意。

original = [1, 2, 3]
copy = original[:]  # shallow copy
copy[0] = 99
print(original)  # [1, 2, 3]  unchanged

# Nested list pitfall
nested = [[1, 2], [3, 4]]
shallow = nested[:]
shallow[0][0] = 99
print(nested)    # [[99, 2], [3, 4]]  changed!

元组:不可变序列

元组使用圆括号表示,创建后便不能修改。由于元组可哈希,因此可以作为字典键或集合元素,非常适合在网格题中表示 (row, col) 坐标对。

point = (3, 7)
print(point[0])   # 3

# Use as dict key
grid = {}
grid[(0, 0)] = 'start'
grid[(2, 3)] = 'end'
print(grid[(0, 0)])  # start

# Unpacking
x, y = point
print(x, y)  # 3 7

何时使用元组而非列表

如果数据不应改变,请选择元组;如果数据需要改变,请选择列表。元组占用的内存也略少一些,在 Dijkstra 算法的大型堆中,这种差异会逐渐累积。

import sys
a_list  = [1, 2, 3, 4, 5]
a_tuple = (1, 2, 3, 4, 5)
print(sys.getsizeof(a_list))   # e.g. 104 bytes
print(sys.getsizeof(a_tuple))  # e.g. 80 bytes

# Tuple returned from function
def min_max(nums):
    return min(nums), max(nums)

lo, hi = min_max([3, 1, 4, 1, 5])
print(lo, hi)  # 1 5

切片中的差一位错误

差一位错误是数组题中最常见的陷阱。请记住,lst[i:j] 恰好会得到 j-i 个元素。要从中间分割,左半部分是 lst[:mid],右半部分是 lst[mid:]。

lst = [1, 2, 3, 4, 5, 6]
mid = len(lst) // 2    # 3
left  = lst[:mid]      # [1, 2, 3]
right = lst[mid:]      # [4, 5, 6]
print(left, right)

# How many elements?
print(len(lst[2:5]))   # 3  (indices 2,3,4)

面试中的负索引

Python 支持负索引:lst[-1] 表示最后一个元素,lst[-2] 表示倒数第二个元素。请优先使用 lst[-1],而不是 lst[len(lst)-1];面试官会注意到这种更简洁的写法。

s = 'abcde'
print(s[-1])    # 'e'
print(s[-3:])   # 'cde'
print(s[:-2])   # 'abc'  (all except last 2)

nums = [10, 20, 30, 40]
print(nums[-2])   # 30
nums[-1] = 99
print(nums)       # [10, 20, 30, 99]

列表排序与比较

Python 使用 Timsort 进行排序,复杂度为 O(n log n),并且排序稳定。lst.sort() 会原地修改列表;sorted(lst) 会返回一个新列表。请使用 key 参数实现自定义排序顺序。代码中有示例。

words = ['banana', 'fig', 'apple', 'kiwi']
words.sort(key=len)
print(words)  # ['fig', 'kiwi', 'apple', 'banana']

nums = [3, 1, 4, 1, 5]
print(sorted(nums, reverse=True))  # [5, 4, 3, 1, 1]
print(nums)  # unchanged: [3, 1, 4, 1, 5]

迭代时修改列表

这是一个经典陷阱:循环遍历列表时绝不要添加或删除元素,否则可能跳过元素或导致程序崩溃。请改用列表推导式创建一个新列表。

# WRONG — skips elements
nums = [1, 2, 3, 4, 5]
for n in nums:
    if n % 2 == 0:
        nums.remove(n)  # skips 4!
print(nums)  # [1, 3, 5]... but 4 got skipped? Actually removes 2,4

# CORRECT — build new list
nums = [1, 2, 3, 4, 5]
nums = [n for n in nums if n % 2 != 0]
print(nums)  # [1, 3, 5]

循环中的元组解包

元组解包可以让循环保持简洁:enumerate 会提供 (index, value),而 zip 可以同时遍历两个列表。* 剩余项语法会将尾部内容收集到自己的变量中。请查看代码。

nums = [10, 20, 30]
for i, v in enumerate(nums):
    print(i, v)
# 0 10 / 1 20 / 2 30

a = [1, 2, 3]
b = ['x', 'y', 'z']
for x, y in zip(a, b):
    print(x, y)

first, *rest = [1, 2, 3, 4]
print(first, rest)  # 1 [2, 3, 4]

快速测验

快速检查一下,看看您对 Python 列表、元组和切片掌握了多少。您一定可以做到。💪

课程回顾

回顾一下:列表是支持 O(1) append 的动态数组,切片总会返回一个新的副本,而元组不可变且可哈希。接下来我们将学习字典和集合。

常见问题解答

「列表、元组与切片」课时是免费的吗?

是的 — 「列表、元组与切片」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 DSA Interview Prep 课程的其余内容,请升级到 CoddyKit PRO。 DSA Interview Prep 课程共包含 4 节课。

「列表、元组与切片」这节课中我会学到什么?

通过经典编程题中的实践示例,掌握 Python 列表操作、切片语法和元组不可变性。 你通过在浏览器中直接运行的动手代码来练习 DSA Interview Prep,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 DSA Interview Prep 需要有经验吗?

无需任何先前经验。CoddyKit 上的 DSA Interview Prep 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 1 节课,共 4 节。

「列表、元组与切片」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 DSA Interview Prep 课中编写并运行代码吗?

能。每节 DSA Interview Prep 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 列表、元组与切片
  2. Python 中的字典与集合
  3. 推导式与内置函数
  4. 函数、闭包与 Lambda
← 返回 DSA Interview Prep