Python 字典:高效映射与查找核心技术
10. 字典
本章介绍Python内置类型——字典。它是Python最强大的特性之一,也是许多高效优雅算法的基石。我们将用字典统计一本书中的唯一单词数量与每个单词的出现次数,并在练习中用字典解决单词谜题。
10.1 字典是一种映射
字典和列表相似,但通用性更强。列表的索引必须是整数,而字典的键几乎可以是任意类型。
# 创建数字单词列表lst = ['zero', 'one', 'two']# 使用整数索引获取对应单词lst[1]
运行结果:
'one'
使用字典实现反向查找:
# 创建空字典numbers = {}# 添加键值对,键为字符串,值为整数numbers['zero'] = 0numbers['one'] = 1numbers['two'] = 2numbers
运行结果:
{'zero': 0, 'one': 1, 'two': 2}
通过键获取对应的值:
numbers['two']
运行结果:
2
键不存在时会触发KeyError:
numbers['three']
运行结果:
KeyError: 'three'
使用len()函数获取键值对数量:
len(numbers)
运行结果:
3
10.2 创建字典
直接创建字典
numbers = {'zero': 0, 'one': 1, 'two': 2}
使用dict()函数创建
# 创建空字典empty = dict()empty
运行结果:
{}
# 复制已有字典numbers_copy = dict(numbers)numbers_copy
运行结果:
{'zero': 0, 'one': 1, 'two': 2}
10.3 in运算符
in运算符用于判断键是否存在于字典中:
numbers = {'zero': 0, 'one': 1, 'two': 2}'one'in numbers
运行结果:
True
in运算符不会检查值:
1in numbers
运行结果:
False
使用values()方法判断值是否存在:
1in numbers.values()
运行结果:
True
字典的高效查找特性
字典基于哈希表实现,in操作的时间复杂度为常数级:
# 读取单词列表文件word_list = open('words.txt').read().split()len(word_list)
运行结果:
113783
# 反转单词的函数defreverse_word(word):# 将字符串反转后重新拼接return''.join(reversed(word))
# 低效版本:使用列表查找deftoo_slow(): count = 0for word in word_list:if reverse_word(word) in word_list: count += 1return count
# 将单词列表转为字典,用于快速查找word_dict = {}for word in word_list: word_dict[word] = 1# 高效版本:使用字典查找defmuch_faster(): count = 0for word in word_dict:if reverse_word(word) in word_dict: count += 1return count
10.4 计数器集合
使用字典统计字符串中各字符出现次数:
# 统计字符串中每个字符的出现次数defvalue_counts(string): counter = {}for letter in string:if letter notin counter:# 字符首次出现,计数为1 counter[letter] = 1else:# 字符已存在,计数加1 counter[letter] += 1return counter
counter = value_counts('brontosaurus')counter
运行结果:
{'b': 1, 'r': 2, 'o': 2, 'n': 1, 't': 1, 's': 2, 'a': 1, 'u': 2}
10.5 遍历字典
遍历字典默认遍历键:
counter = value_counts('banana')for key in counter:print(key)
运行结果:
ban
遍历字典的值:
for value in counter.values():print(value)
运行结果:
132
同时遍历键和值:
for key in counter: value = counter[key]print(key, value)
运行结果:
b 1a 3n 2
10.6 列表与字典
列表可以作为字典的值,但不能作为键:
# 列表作为字典的值(合法)d = {4: ['r', 'o', 'u', 's']}d
运行结果:
{4: ['r', 'o', 'u', 's']}
# 列表作为字典的键(非法,列表不可哈希)letters = list('abcd')d[letters] = 4
运行结果:
TypeError: unhashable type: 'list'
10.7 累积列表
遍历字典并筛选生成新列表:
# 判断单词是否为回文词defis_palindrome(word):# 反转单词后与原单词比较return reverse_word(word) == word
# 统计回文词数量count = 0for word in word_dict:if is_palindrome(word): count += 1count
运行结果:
91
# 生成回文词列表palindromes = []for word in word_dict:if is_palindrome(word): palindromes.append(word)# 查看前10个回文词palindromes[:10]
运行结果:
['aa', 'aba', 'aga', 'aha', 'ala', 'alula', 'ama', 'ana', 'anna', 'ava']
# 筛选长度大于等于7的长回文词long_palindromes = []for word in palindromes:iflen(word) >= 7: long_palindromes.append(word)long_palindromes
运行结果:
['deified', 'halalah', 'reifier', 'repaper', 'reviver', 'rotator', 'sememes']
10.8 备忘录
使用字典缓存递归结果,大幅提升效率:
# 低效递归斐波那契函数deffibonacci(n):if n == 0:return0if n == 1:return1return fibonacci(n-1) + fibonacci(n-2)
# 备忘录字典,缓存已计算的结果known = {0: 0, 1: 1}# 备忘录优化版斐波那契函数deffibonacci_memo(n):if n in known:# 结果已缓存,直接返回return known[n]# 计算新结果 res = fibonacci_memo(n-1) + fibonacci_memo(n-2)# 存入缓存 known[n] = resreturn res
10.9 调试
处理大数据集的调试建议:
10.10 术语表
10.11 练习
10.11.2 使用get()简化计数器
# 使用get方法简化字符统计,无需if语句defvalue_counts(string): counter = {}for letter in string:# 键不存在时返回默认值0 counter[letter] = counter.get(letter, 0) + 1return counter
10.11.3 判断重复元素
# 判断序列中是否存在重复元素defhas_duplicates(seq): seen = set()for item in seq:if item in seen:returnTrue seen.add(item)returnFalse
10.11.4 查找重复键
# 返回计数值大于1的键列表deffind_repeats(counter): repeats = []for key, value in counter.items():if value > 1: repeats.append(key)return repeats
10.11.5 合并计数器
# 合并两个计数字典,相同键的值相加defadd_counters(c1, c2): result = c1.copy()for key, value in c2.items(): result[key] = result.get(key, 0) + valuereturn result
10.11.6 交错单词判断
# 判断单词是否可拆分为两个交错的有效单词defis_interlocking(word):# 提取偶数位置字符 first = word[0::2]# 提取奇数位置字符 second = word[1::2]return first in word_dict and second in word_dict```当前文件内容过长,豆包只阅读了前 74%。---