68、编写一行代码,将值 6 追加到列表 t 中第二个列表的末尾。如果显示 t,结果应该是 ([1, 2, 3], [4, 5, 6])。
t = ([1, 2, 3], [4, 5])
t[1].append(6)
print(t)
69、尝试创建一个将 t 映射到字符串的字典,并确认你会得到一个类型错误。
代码
尝试创建将
d = {t: 'this tuple contains two lists'}
映射到字符串的字典,但
t
未定义,运行时会因
t
未定义而报错,若
t
为不可哈希类型(如列表)也会产生
t
。
TypeError
要确认
,需保证
TypeError
是不可哈希类型,比如列表。示例代码如下:
t
t = [1, 2, 3]
d = {t: 'this tuple contains two lists'}
运行该代码会得到
。
TypeError
70、编写一个名为 shift_word 的函数,该函数接受一个字符串和一个整数作为参数,并返回一个新字符串,新字符串中的字母是原字符串中的字母按给定的位数进行移位后的结果。为了测试你的函数,请确认 “cheer” 移位 7 位后是 “jolly”,“melon” 移位 16 位后是 “cubed”。
以下是实现
函数的 Python 代码:
shift_word
def shift_word(word, shift):
result = ''
for letter in word:
if letter.isalpha():
start = ord('a') if letter.islower() else ord('A')
new_letter = chr((ord(letter) - start + shift) % 26 + start)
result += new_letter
else:
result += letter
return result
# 测试函数
print(shift_word("cheer", 7)) # 输出: jolly
print(shift_word("melon", 16)) # 输出: cubed
上述代码定义了
函数,它遍历输入字符串中的每个字母,对字母进行移位操作,并处理字母循环(从 ‘z’ 回到 ‘a’)的情况。最后返回移位后的新字符串。通过测试用例可以验证函数的正确性。
shift_word
71、编写一个名为most_frequent_letters的函数,该函数接受一个字符串,并按字母出现频率降序打印字母。
以下是实现该功能的Python代码:
from collections import Counter
def most_frequent_letters(s):
counter = Counter(s)
items = counter.items()
sorted_items = sorted(items, key=lambda item: item[1], reverse=True)
for letter, freq in sorted_items:
print(letter, end=' ')
72、编写一个程序,该程序接收一个单词列表,并打印出所有由变位词组成的单词集合。
以下给出两种实现方式的代码示例。第一种是使用普通字典的方式:
def signature(word):
return ''.join(sorted(word))
def all_anagrams(word_list):
d = {}
for word in word_list:
t = signature(word)
if t not in d:
d[t] = [word]
else:
d[t].append(word)
result = [values for values in d.values() if len(values) > 1]
for anagram_set in result:
print(anagram_set)
# 示例调用
word_list = ['deltas', 'desalt', 'lasted', 'salted', 'slated', 'retainers', 'ternaries', 'generating', 'greatening', 'resmelts', 'smelters', 'termless', 'spot', 'stop', 'tops']
all_anagrams(word_list)
第二种是使用
的方式:
defaultdict
from collections import defaultdict
def signature(word):
return ''.join(sorted(word))
def all_anagrams(word_list):
d = defaultdict(list)
for word in word_list:
t = signature(word)
d[t].append(word)
result = [values for values in d.values() if len(values) > 1]
for anagram_set in result:
print(anagram_set)
# 示例调用
word_list = ['deltas', 'desalt', 'lasted', 'salted', 'slated', 'retainers', 'ternaries', 'generating', 'greatening', 'resmelts', 'smelters', 'termless', 'spot', 'stop', 'tops']
all_anagrams(word_list)
以上代码中,
函数用于对单词的字母进行排序并拼接成新字符串,
signature
函数用于找出所有变位词组并打印。
all_anagrams
73、编写一个名为
word_distance
的函数,该函数接受两个长度相同的单词,并返回这两个单词中字母不同的位置数量。
word_distance
以下是实现该功能的 Python 代码:
def word_distance(word1, word2):
distance = 0
for i in range(len(word1)):
if word1[i] != word2[i]:
distance += 1
return distance
74、编写一个程序,找出单词列表中所有的换位词对。
以下是一个可以找出单词列表中所有换位词对的 Python 程序示例:
# 读取单词列表
word_list = []
with open('words.txt') as f:
for line in f:
word = line.strip()
word_list.append(word)
# 定义函数判断两个单词是否为换位词对
def is_metathesis_pair(word1, word2):
if sorted(word1) != sorted(word2):
return False
diff_count = 0
for a, b in zip(word1, word2):
if a != b:
diff_count += 1
return diff_count == 2
# 找出所有换位词对
metathesis_pairs = []
for i in range(len(word_list)):
for j in range(i + 1, len(word_list)):
word1 = word_list[i]
word2 = word_list[j]
if is_metathesis_pair(word1, word2):
metathesis_pairs.append((word1, word2))
# 输出结果
for pair in metathesis_pairs:
print(pair)
此程序先读取
文件获取单词列表,接着定义
words.txt
函数来判断两个单词是否为换位词对,最后通过两层循环遍历单词列表找出所有换位词对并输出。
is_metathesis_pair
75、询问虚拟助手字典中的
setdefault
方法如何工作,或者将
add_word
代码复制到虚拟助手中并询问“能否使用
setdefault
重写此代码?”
setdefault
add_word
setdefault
你可以向虚拟助手询问“字典中的
方法如何工作”,或者把
setdefault
代码复制给虚拟助手并问“能否使用
add_word
重写此代码”来获取相关帮助。
setdefault
76、编写一个函数来统计每个三元组(三个单词的序列)出现的次数。提示:编写一个名为
count_trigram
的函数,它类似于
count_bigram
。然后编写一个名为
process_word_trigram
的函数,它类似于
process_word_bigram
。
count_trigram
count_bigram
process_word_trigram
process_word_bigram
以下是具体实现的 Python 代码:
# 用于存储三元组及其出现次数的字典
trigram_counter = {}
# 统计三元组出现次数的函数
def count_trigram(trigram):
key = tuple(trigram)
if key not in trigram_counter:
trigram_counter[key] = 1
else:
trigram_counter[key] += 1
# 处理单词以统计三元组的函数
window = []
def process_word_trigram(word):
window.append(word)
if len(window) == 3:
count_trigram(window)
window.pop(0) # 移除窗口中的第一个单词,以便滑动窗口
77、从
add_bigram
开始,编写一个名为
add_trigram
的函数,该函数接受一个包含三个单词的列表,使用前两个单词作为键,第三个单词作为可能的后继词,在
successor_map
中添加或更新一个条目。
add_bigram
add_trigram
successor_map
以下是
函数的实现:
add_trigram
# 假设 successor_map 是一个全局变量或在函数外部定义的字典
successor_map = {}
def add_trigram(words):
if len(words) != 3:
raise ValueError("输入的列表必须包含三个单词。")
bigram = (words[0], words[1])
successor = words[2]
if bigram in successor_map:
successor_map[bigram].append(successor)
else:
successor_map[bigram] = [successor]
return successor_map
这个函数首先检查输入的列表是否包含三个单词,如果不是则抛出异常。然后,它将前两个单词组成一个二元组作为键,第三个单词作为后继词。如果这个键已经存在于
中,就将后继词添加到对应的列表中;如果不存在,就创建一个新的键值对。最后返回更新后的
successor_map
。
successor_map
78、临时程序和持久程序有什么区别?
临时程序通常运行时间短,结束时数据会丢失,每次运行都重新开始;
持久程序运行时间长甚至持续运行,会将部分数据存于长期存储设备中,关闭再重启时能从上次中断处继续。
79、相对路径和绝对路径有什么区别?
相对路径从当前工作目录或其他指定目录开始,依赖于当前目录;绝对路径不依赖于当前目录。
80、当我读取文件时,二进制模式和文本模式有什么区别?
在二进制模式下,文件内容被视为字节序列,不会被解释为文本;而文本模式通常会将内容解释为字符序列。
81、什么是哈希函数?
哈希函数是一种接受一个对象并计算出一个整数的函数,该整数用于在哈希表中定位键。它接受文件内容并计算出一个摘要,通常是一个大整数。如果两个文件包含相同的数据,它们将具有相同的摘要;如果两个文件不同,它们几乎总是具有不同的摘要。
82、什么是MD5摘要?
MD5摘要通常是一个大整数,是使用
模块中的
hashlib
哈希函数,对文件内容进行计算得到的。可以通过
md5
方法将其以十六进制数字字符串的形式呈现。如果两个文件包含相同数据,它们的MD5摘要相同;若不同,几乎总是有不同的MD5摘要。
hexdigest
83、编写一个名为 replace_all 的函数,该函数接受一个模式字符串、一个替换字符串和两个文件名作为参数。它应该读取第一个文件,并将内容写入第二个文件(必要时创建该文件)。如果模式字符串出现在内容的任何位置,都应该将其替换为替换字符串。为了测试你的函数,读取 photos/notes.txt 文件,并将其中的 photos 替换为 images。
以下是实现
函数的 Python 代码:
replace_all
def replace_all(pattern, replacement, file1, file2):
try:
with open(file1, 'r', encoding='utf-8') as f1:
content = f1.read()
content = content.replace(pattern, replacement)
with open(file2, 'w', encoding='utf-8') as f2:
f2.write(content)
except FileNotFoundError:
print(f'文件 {file1} 未找到。')
# 测试函数
replace_all('photos', 'images', 'photos/notes.txt', 'new_notes.txt')
上述代码定义了
函数,它会读取第一个文件的内容,将模式字符串替换为替换字符串,然后将结果写入第二个文件。最后调用该函数进行测试,将
replace_all
中的
photos/notes.txt
替换为
photos
,并将结果写入
images
文件。
new_notes.txt
84、在“存储数据结构”中,我们使用
shelve
模块创建了一个键值存储,将字母排序后的字符串映射到一组变位词列表。为完成这个示例,请编写一个名为
add_word
的函数,该函数接受一个字符串和一个
shelf
对象作为参数。它应该对单词的字母进行排序以生成一个键,然后检查该键是否已经存在于
shelf
中。如果不存在,它应该创建一个包含新单词的列表,并将其添加到
shelf
中。如果存在,它应该将新单词追加到现有的值中。
shelve
add_word
shelf
shelf
shelf
以下是实现
函数的Python代码:
add_word
import shelve
def sort_word(word):
return ''.join(sorted(word))
def add_word(word, db):
key = sort_word(word)
if key not in db:
db[key] = [word]
else:
anagram_list = db[key]
anagram_list.append(word)
db[key] = anagram_list
85、要识别图像文件,请编写一个名为 is_image 的函数,该函数接受一个路径和一个文件扩展名列表作为参数。如果路径以列表中的某个扩展名结尾,则返回 True。提示:使用 os.path.splitext。
以下是实现
函数的 Python 代码:
is_image
import os
def is_image(path, extensions):
file_ext = os.path.splitext(path)[1].lower()
return file_ext in [ext.lower() for ext in extensions]
这个函数首先使用
获取文件的扩展名,然后将其转换为小写。接着检查该扩展名是否在传入的扩展名列表中(列表中的扩展名也都转换为小写),如果存在则返回
os.path.splitext
,否则返回
True
。
False
86、编写一个名为 add_path 的函数,该函数接受一个路径和一个 shelf 对象作为参数。它应该使用 md5_digest 来计算文件内容的摘要。然后更新 shelf,要么创建一个新项,将摘要映射到包含该路径的列表,要么如果该列表已存在,则将路径追加到列表中。
以下是实现
函数的 Python 代码示例:
add_path
import hashlib
def md5_digest(path):
hash_md5 = hashlib.md5()
with open(path, "rb") as f:
for chunk in iter(lambda: f.read(4096), b""):
hash_md5.update(chunk)
return hash_md5.hexdigest()
def add_path(path, shelf):
digest = md5_digest(path)
if digest not in shelf:
shelf[digest] = [path]
else:
shelf[digest].append(path)
return shelf
在上述代码中,
函数用于计算文件内容的 MD5 摘要,
md5_digest
函数使用
add_path
计算文件摘要,并根据摘要是否已存在于
md5_digest
中,创建新项或追加路径到现有列表。
shelf
87、编写一个名为 process_path 的函数,该函数接受一个路径、一个架子(shelf)和一个图像文件扩展名列表作为参数,使用 is_image 函数检查该路径是否为图像文件,并使用 add_path 函数将其添加到架子(shelf)中。
以下是实现该功能的 Python 代码示例:
import os
def is_image(path, extensions):
return os.path.splitext(path)[1].lower() in extensions
def md5_digest(file_path):
# 这里简单模拟,实际需要实现 MD5 计算
return 'digest'
def add_path(path, shelf):
digest = md5_digest(path)
if digest in shelf:
shelf[digest].append(path)
else:
shelf[digest] = [path]
return shelf
def process_path(path, shelf, image_extensions):
if is_image(path, image_extensions):
add_path(path, shelf)
return shelf
在上述代码中,
函数接收一个路径、架子和图像文件扩展名列表作为参数。它首先使用
process_path
函数检查该路径是否为图像文件,如果是,则使用
is_image
函数将其添加到架子中。
add_path
88、与修改器相比,纯函数的优缺点是什么?
优点:
使用纯函数的程序可能比使用修改器的程序更不容易出错 可以避免修改传入的对象,程序更具可维护性和可预测性
缺点:
不如修改器方便 效率可能较低
89、在Python的f-string中可以使用哪些格式说明符?
在Python的f-string中,可使用如
这样的格式说明符,它表示以至少两位数显示,必要时前面补零。例如
':02d'
和
'{lunch.minute:02d}'
,能让分钟和秒以至少两位数且必要时带前导零的形式显示。
'{lunch.second:02d}'
90、编写一个名为subtract_time的函数,该函数接受两个表示同一天内时间的对象,并返回它们之间的间隔(以秒为单位)。假设存在一个名为time_to_int的函数,它可以将时间对象转换为对应的秒数。
可以借助已有的
函数来实现
time_to_int
函数,以下是示例代码:
subtract_time
def subtract_time(t1, t2):
return abs(time_to_int(t1) - time_to_int(t2))
这里使用
函数确保返回的秒数为非负值。
abs
91、编写一个名为 is_after 的函数,该函数接受两个 Time 对象,如果第二个时间在当天晚于第一个时间,则返回 True,否则返回 False。
以下是实现该功能的 Python 代码示例:
class Time:
def __init__(self, hour, minute, second):
self.hour = hour
self.minute = minute
self.second = second
def time_to_int(self):
return self.hour * 3600 + self.minute * 60 + self.second
def is_valid(self):
if self.hour < 0 or self.minute < 0 or self.second < 0:
return False
if self.minute >= 60 or self.second >= 60:
return False
if not isinstance(self.hour, int) or not isinstance(self.minute, int) or not isinstance(self.second, int):
return False
return True
def is_after(self, other):
assert self.is_valid(), 'self is invalid'
assert other.is_valid(), 'other is invalid'
return self.time_to_int() < other.time_to_int()
你可以使用以下方式调用这个函数:
t1 = Time(10, 30, 0)
t2 = Time(12, 0, 0)
print(t1.is_after(t2)) # 输出 True