Python 数据结构(Java 对照)

从 Java 转向 Python 时,经典数据结构的用法对照与踩坑记录

Python 数据结构(Java 对照)

这篇笔记是我从 Java 切到 Python 时,对常见数据结构做的一次对照整理。核心目标是两件事:

  • 快速把 Java 里的习惯映射到 Python
  • 避免在刷题和业务代码中踩性能和语义坑

总览对照

场景Java 常见写法Python 常见写法
动态数组ArrayListlist
哈希映射HashMapdict
哈希集合HashSetset
ArrayDeque / Stacklist
队列 / 双端队列ArrayDequecollections.deque
小顶堆PriorityQueueheapq + list

数组与动态列表(Array / ArrayList)

# Java: List<Integer> list = new ArrayList<>()
arr = []

# Java: list.add(1)
arr.append(1)

# Java: list.get(i)
arr[0]

# Java: list.size() / arr.length
len(arr)

# Java: list.remove(list.size() - 1)
arr.pop()

# Java: list.subList(start, end)  # 左闭右开
sub = arr[start:end]

我补充的点:

  • Python list 头部插入/删除是 O(n),大量队列操作不要用它,改用 deque
  • 切片 arr[a:b] 会返回新列表,不是视图

哈希映射(HashMap / Dict)

# Java: Map<String, Integer> map = new HashMap<>()
tmap = {}

# Java: map.put("apple", 1)
tmap["apple"] = 1

# Java: map.containsKey("apple")
"apple" in tmap

# Java: map.get("apple")
# 注意:如果 key 不存在会抛 KeyError
tmap["apple"]

# Java: map.getOrDefault("apple", 0)
tmap.get("apple", 0)

# Java: map.remove("apple")
del tmap["apple"]

# Java: for (String key : map.keySet())
for key in tmap:
    pass

# Java: for (Map.Entry<String, Integer> entry : map.entrySet())
for key, value in tmap.items():
    pass

我补充的点:

  • del tmap[k] 在 key 不存在时会报错;更稳妥可以用 tmap.pop(k, None)
  • 高频计数建议直接用 collections.Counterdefaultdict(int)

哈希集合(HashSet / Set)

# Java: Set<Integer> set = new HashSet<>()
tset = set()

# Java: set.add(1)
tset.add('a')

# Java: set.contains(1)
'a' in tset

# Java: set.remove(1)  # 不存在会报错
tset.remove('a')

# Python 专属:不存在不报错
tset.discard('a')

# Java: set.size()
len(tset)

我补充的点:

  • set 无序,不要依赖迭代顺序
  • 去重保序要用 dict.fromkeys(seq) 或手动维护

栈与双端队列(Deque / Stack / Queue)

from collections import deque

# 栈(后进先出)
# Java: Deque<Integer> stack = new ArrayDeque<>()
stack = []
stack.append(1)   # push
stack.pop()       # pop
# peek 前先判空
if stack:
    top = stack[-1]

# 队列(先进先出)
# Java: Deque<Integer> queue = new ArrayDeque<>()
queue = deque()
queue.append(1)       # addLast
queue.appendleft(2)   # addFirst
queue.popleft()       # pollFirst
queue.pop()           # pollLast
if queue:
    head = queue[0]   # peekFirst
if not queue:
    pass

我补充的点:

  • Python 里“队列”优先用 deque,不要用 list.pop(0)
  • 访问栈顶/队头前先判空,避免 IndexError

堆 / 优先队列(PriorityQueue / Heap)

import heapq

# Java: PriorityQueue<Integer> pq = new PriorityQueue<>()
heap = []
heapq.heappush(heap, 5)  # offer
heapq.heappush(heap, 2)
heapq.heappop(heap)      # poll

# peek
if heap:
    top = heap[0]

# Python 只内置小顶堆
# Java maxHeap: new PriorityQueue<>((a, b) -> b - a)
max_heap = []
heapq.heappush(max_heap, -5)
heapq.heappush(max_heap, -2)
val = -heapq.heappop(max_heap)

我补充的点:

  • heapq 不是完整容器类,而是“对 list 做堆操作的函数集”
  • 想要固定容量 topK,常用“小顶堆保留 K 个元素”

我常用的安全写法模板

# dict 安全读取
v = tmap.get("k", 0)

# dict 安全删除
tmap.pop("k", None)

# 栈/队列取值前判空
if stack:
    x = stack[-1]

if queue:
    y = queue[0]

# 堆顶读取前判空
if heap:
    z = heap[0]

阶段总结

从 Java 切到 Python 后,我的主要变化是:

  • 少关注“类名”,多关注“操作复杂度”
  • 队列优先 deque,堆优先 heapq
  • 字典和集合的“存在性判断 + 安全访问”写法要形成肌肉记忆

后续我会继续补一篇:排序 / 二分 / 前缀和 / 单调栈 在 Python 里的模板化写法。