python中的dict()
在 Python 中,dict() 是创建字典的内置函数,字典是一种键值对(key-value pair)的数据结构。由于字典具有高效的键值查找、插入和删除操作,在 LeetCode 刷题中非常常用,尤其是处理映射关系、快速查找、计数、前缀匹配等问题时。
基本特性
- 键值对存储:字典中的每个元素是一个键值对,形式为
key: value。 - 键的唯一性:字典的键必须唯一,重复键会覆盖之前的值。
- 可变性:字典支持动态添加、修改和删除键值对。
- 键必须可哈希:键可以是字符串、数字或元组等不可变类型,不能是列表或字典。
常见用法和语法
1. 创建字典
- 空字典
d = {} print(d) # 输出: {} - 通过
dict()创建d = dict(a=1, b=2) print(d) # 输出: {'a': 1, 'b': 2} - 通过键值对创建
d = {'key1': 'value1', 'key2': 'value2'} print(d) # 输出: {'key1': 'value1', 'key2': 'value2'}
2. 访问和修改字典
-
访问值
d = {'a': 1, 'b': 2} print(d['a']) # 输出: 1如果键不存在,直接访问会报错。
-
使用
get()方法print(d.get('c', 'default')) # 输出: 'default'如果键不存在,返回默认值
default。 -
添加或修改键值对
d['c'] = 3 print(d) # 输出: {'a': 1, 'b': 2, 'c': 3}
3. 删除元素
- 使用
deldel d['a'] print(d) # 输出: {'b': 2, 'c': 3} - 使用
pop()value = d.pop('b', 'default') print(value) # 输出: 2 print(d) # 输出: {'c': 3}
4. 遍历字典
- 遍历键
for key in d: print(key) - 遍历值
for value in d.values(): print(value) - 遍历键值对
for key, value in d.items(): print(key, value)
5. 字典推导式
- 快速创建字典
squares = {x: x**2 for x in range(5)} print(squares) # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
在算法题中,字典(dict)是最常用的数据结构之一,主要用于高效查找、计数和映射。以下是针对算法竞赛的字典核心方法与应用场景总结:
一、高频方法速查表
| 方法 | 时间复杂度 | 典型应用场景 | 示例 |
|---|---|---|---|
dict.get(key, default) |
O(1) | 安全访问(防KeyError) | counts.get(x, 0) |
dict.setdefault(key, default) |
O(1) | 初始化复合值 | dict.setdefault(k, []).append(v) |
dict.keys() |
O(1)* | 遍历键 | for k in d:(直接迭代) |
dict.values() |
O(1)* | 遍历值 | sum(d.values()) |
dict.items() |
O(1)* | 遍历键值对 | for k, v in d.items() |
key in dict |
O(1) | 成员检查 | if k in d: |
dict.pop(key, default) |
O(1) | 删除并返回值 | d.pop('old', None) |
dict.update(other_dict) |
O(len(other)) | 合并字典 | d1.update(d2) |
collections.defaultdict |
- | 自动初始化缺失键 | dd = defaultdict(int) |
collections.Counter |
- | 频率统计 | Counter(arr).most_common(2) |
注:
keys()/values()/items()在Python 3中返回视图对象,实际迭代O(n)
二、算法题核心应用场景
1. 频率统计(Top K元素)
from collections import Counter
arr = [1, 2, 2, 3, 3, 3]
cnt = Counter(arr)
# 获取最高频的2个元素
print(cnt.most_common(2)) # [(3, 3), (2, 2)]
# 手动实现
freq = {}
for x in arr:
freq[x] = freq.get(x, 0) + 1
top_k = sorted(freq.items(), key=lambda x: x[1], reverse=True)[:2]
2. 索引映射(两数之和)
def two_sum(nums, target):
seen = {} # 值->索引映射
for i, n in enumerate(nums):
complement = target - n
if complement in seen:
return [seen[complement], i]
seen[n] = i
return []
3. 分组归类(相同字母异位词)
words = ["eat", "tea", "tan", "ate", "nat", "bat"]
groups = {}
for w in words:
key = ''.join(sorted(w)) # 排序后的字符串作为键
groups.setdefault(key, []).append(w)
print(list(groups.values())) # [['eat','tea','ate'], ['tan','nat'], ['bat']]
4. 状态缓存(动态规划/记忆化搜索)
memo = {}
def fib(n):
if n <= 1: return n
if n not in memo:
memo[n] = fib(n-1) + fib(n-2)
return memo[n]
5. 最近访问记录(LRU缓存)
from collections import OrderedDict
class LRUCache:
def __init__(self, capacity):
self.cache = OrderedDict()
self.cap = capacity
def get(self, key):
if key not in self.cache: return -1
self.cache.move_to_end(key) # 标记为最近使用
return self.cache[key]
def put(self, key, value):
if key in self.cache:
self.cache.move_to_end(key)
self.cache[key] = value
if len(self.cache) > self.cap:
self.cache.popitem(last=False) # 移除最旧项
三、进阶技巧
1. 复合键(元组作为键)
# 坐标统计
points = [(1,2), (3,4), (1,2)]
coord_count = {}
for p in points:
coord_count[p] = coord_count.get(p, 0) + 1
print(coord_count) # {(1,2): 2, (3,4): 1}
2. 字典模拟图结构
graph = {
'A': ['B', 'C'],
'B': ['D'],
'C': ['E'],
'D': [],
'E': ['B']
}
# BFS遍历
from collections import deque
def bfs(start):
visited = set()
queue = deque([start])
while queue:
node = queue.popleft()
if node in visited:
continue
visited.add(node)
for neighbor in graph.get(node, []):
queue.append(neighbor)
3. 双向映射(双字典)
# 维护一一对应关系
forward_map = {}
reverse_map = {}
def add_pair(a, b):
if a in forward_map or b in reverse_map:
return False
forward_map[a] = b
reverse_map[b] = a
return True
def remove_by_a(a):
if a not in forward_map: return
b = forward_map[a]
del forward_map[a]
del reverse_map[b]
四、性能注意事项
- 避免频繁创建字典:在循环外初始化字典
- 优先用
in检查:而非try-except KeyError(除非异常概率>25%) - 视图对象高效操作:
d = {'a':1, 'b':2} keys_view = d.keys() # 支持集合操作 print(keys_view & {'a', 'c'}) # {'a'} - 字典推导式:
# 快速创建字典 square_dict = {x: x*x for x in range(5)} # {0:0, 1:1, 2:4, ...}
五、常见坑点
- 可变对象作为键:
# 列表不可哈希,需转元组 valid_dict = {tuple([1,2]): "value"} # 正确 # invalid_dict = {[1,2]: "value"} # TypeError - 字典顺序依赖:
# Python 3.6以下版本无顺序保证 # 需有序时显式使用OrderedDict - 默认值陷阱:
# 使用defaultdict时避免共享引用 dd = defaultdict(list) # 安全:每次创建新列表 # dd = defaultdict(lambda: []) # 等效写法
LeetCode 中常用场景
1. 统计频率
统计字符或数字的出现次数:
nums = [1, 2, 2, 3, 3, 3]
count = {}
for num in nums:
count[num] = count.get(num, 0) + 1
print(count) # 输出: {1: 1, 2: 2, 3: 3}
2. 检查映射关系
判断两个字符串是否存在一一映射:
def isIsomorphic(s, t):
mapping_s_t = {}
mapping_t_s = {}
for c1, c2 in zip(s, t):
if c1 in mapping_s_t and mapping_s_t[c1] != c2:
return False
if c2 in mapping_t_s and mapping_t_s[c2] != c1:
return False
mapping_s_t[c1] = c2
mapping_t_s[c2] = c1
return True
3. 前缀匹配
用于实现 Trie(字典树)相关题目:
class Trie:
def __init__(self):
self.children = {}
self.is_end = False
def insert(self, word):
node = self
for char in word:
if char not in node.children:
node.children[char] = Trie()
node = node.children[char]
node.is_end = True
4. 两数之和
使用字典快速查找补数:
def twoSum(nums, target):
d = {}
for i, num in enumerate(nums):
if target - num in d:
return [d[target - num], i]
d[num] = i
5. 滑动窗口问题
用字典记录窗口内字符频率:
def lengthOfLongestSubstring(s):
char_index = {}
start = max_len = 0
for i, char in enumerate(s):
if char in char_index and char_index[char] >= start:
start = char_index[char] + 1
char_index[char] = i
max_len = max(max_len, i - start + 1)
return max_len
效率优势
- 查找:字典的查找操作时间复杂度为 ( O(1) )。
- 插入和删除:字典的插入和删除操作也为 ( O(1) ),适合大规模数据的快速操作。
- 遍历:遍历时间复杂度为 ( O(n) ),取决于字典中元素的数量。
在 LeetCode 中,利用字典可以显著优化性能,尤其在需要频繁查找、统计或建立映射关系的题目中。

浙公网安备 33010602011771号