Python编程:文件、异常与递归问题的解决方案
在Python编程中,文件操作、异常处理以及递归算法是非常重要的部分。下面将为大家介绍一系列相关问题的解决方案。
1. 文件头部与尾部显示
- 显示文件头部 :要显示文件的前10行,可使用以下代码:
import sys
NUM_LINES = 10
if len(sys.argv) != 2:
print("Provide the file name as a command line argument.")
quit()
try:
inf = open(sys.argv[1], "r")
line = inf.readline()
count = 0
while count < NUM_LINES and line != "":
line = line.rstrip()
count = count + 1
print(line)
line = inf.readline()
inf.close()
except IOError:
print("An error occurred while accessing the file.")
操作步骤如下:
1. 检查命令行参数是否只包含一个文件名。
2. 尝试打开文件。
3. 逐行读取文件,读取并显示前10行。
4. 关闭文件。若出现异常,显示错误信息。
- 显示文件尾部 :显示文件的最后10行,代码如下:
import sys
NUM_LINES = 10
if len(sys.argv) != 2:
print("Provide the file name as a command line argument.")
quit()
try:
inf = open(sys.argv[1], "r")
lines = []
for line in inf:
lines.append(line)
if len(lines) > NUM_LINES:
lines.pop(0)
inf.close()
except:
print("An error occurred while processing the file.")
quit()
for line in lines:
print(line, end="")
操作步骤:
1. 检查命令行参数。
2. 打开文件,逐行读取,始终保存最近的10行。
3. 关闭文件。若出现异常,显示错误信息并退出。
4. 显示最后10行。
2. 文件拼接
要将一个或多个文件拼接并显示结果,代码如下:
import sys
if len(sys.argv) == 1:
print("You must provide at least one file name.")
quit()
for i in range(1, len(sys.argv)):
fname = sys.argv[i]
try:
inf = open(fname, "r")
for line in inf:
print(line, end="")
inf.close()
except:
print("Couldn’t open/display", fname)
操作步骤:
1. 检查是否提供了至少一个文件名。
2. 遍历所有文件名,依次打开文件。
3. 显示文件内容,关闭文件。若出现异常,显示错误信息,但继续处理后续文件。
3. 数字求和
计算用户输入数字的总和,忽略非数字输入,代码如下:
line = input("Enter a number: ")
total = 0
while line != "":
try:
num = float(line)
total = total + num
print("The total is now", total)
except ValueError:
print("That wasn’t a number.")
line = input("Enter a number: ")
print("The grand total is", total)
操作步骤:
1. 读取用户输入的第一行。
2. 若输入不为空,尝试将其转换为数字并累加到总和中。
3. 若转换失败,显示错误信息。
4. 继续读取下一个输入,直到用户输入空行。
5. 显示最终总和。
4. 移除Python文件中的注释
移除Python文件中的所有注释(忽略注释字符在字符串中的情况),代码如下:
try:
in_name = input("Enter the name of a Python file: ")
inf = open(in_name, "r")
except:
print("A problem was encountered with the input file.")
print("Quitting...")
quit()
try:
out_name = input("Enter the output file name: ")
outf = open(out_name, "w")
except:
inf.close()
print("A problem was encountered with the output file.")
print("Quitting...")
quit()
try:
for line in inf:
pos = line.find("#")
if pos > -1:
line = line[0 : pos]
line = line + "\n"
outf.write(line)
inf.close()
outf.close()
except:
print("A problem was encountered while processing the file.")
print("Quitting...")
操作步骤:
1. 读取输入文件名并打开输入文件。若打开失败,显示错误信息并退出。
2. 读取输出文件名并打开输出文件。若打开失败,关闭输入文件,显示错误信息并退出。
3. 逐行读取输入文件,查找注释字符,若存在则移除注释。
4. 将修改后的行写入输出文件。
5. 关闭输入和输出文件。若出现异常,显示错误信息并退出。
5. 生成随机密码
生成由两个随机单词拼接而成的密码,密码长度在8到10个字母之间,每个单词至少3个字母,代码如下:
from random import randrange
WORD_FILE = "../Data/words.txt"
words = []
inf = open(WORD_FILE, "r")
for line in inf:
line = line.rstrip()
if len(line) >= 3 and len(line) <= 7:
words.append(line)
inf.close()
first = words[randrange(0, len(words))]
first = first.capitalize()
password = first
while len(password) < 8 or len(password) > 10:
second = words[randrange(0, len(words))]
second = second.capitalize()
password = first + second
print("The random password is:", password)
操作步骤:
1. 从文件中读取所有长度在3到7个字母之间的单词。
2. 随机选择第一个单词并首字母大写。
3. 不断随机选择第二个单词,直到拼接后的密码长度在8到10个字母之间。
4. 显示随机密码。
6. 字母使用比例分析
确定并显示每个字母在单词中出现的比例,找出使用比例最小的字母,代码如下:
WORD_FILE = "../Data/words.txt"
counts = {}
for ch in "ABCDEFGHIJKLMNOPQRSTUVWXYZ":
counts[ch] = 0
num_words = 0
inf = open(WORD_FILE, "r")
for word in inf:
word = word.upper().rstrip()
unique = []
for ch in word:
if ch not in unique and ch >= "A" and ch <= "Z":
unique.append(ch)
for ch in unique:
counts[ch] = counts[ch] + 1
num_words = num_words + 1
inf.close()
smallest_count = min(counts.values())
for ch in sorted(counts):
if counts[ch] == smallest_count:
smallest_letter = ch
percentage = counts[ch] / num_words * 100
print(ch, "occurs in %.2f percent of words" % percentage)
print()
print("The letter that is easiest to avoid is", smallest_letter)
操作步骤:
1. 初始化一个字典,用于记录每个字母出现的次数。
2. 打开文件,逐行读取单词。
3. 提取单词中的唯一字母,更新字典中的计数。
4. 统计处理的单词总数。
5. 关闭文件。
6. 找出出现次数最少的字母。
7. 显示每个字母的使用比例和最容易避免的字母。
7. 最受欢迎的名字
显示1900年到2012年至少有一年最受欢迎的女孩和男孩名字,代码如下:
FIRST_YEAR = 1900
LAST_YEAR = 2012
def LoadAndAdd(fname, names):
inf = open(fname, "r")
line = inf.readline()
inf.close()
parts = line.split()
name = parts[0]
if name not in names:
names.append(name)
def main():
girls = []
boys = []
for year in range(FIRST_YEAR, LAST_YEAR + 1):
girl_fname = "../Data/BabyNames/" + str(year) + "_GirlsNames.txt"
boy_fname = "../Data/BabyNames/" + str(year) + "_BoysNames.txt"
LoadAndAdd(girl_fname, girls)
LoadAndAdd(boy_fname, boys)
print("Girls’ names that reached #1:")
for name in girls:
print(" ", name)
print()
print("Boys’ names that reached #1: ")
for name in boys:
print(" ", name)
main()
操作步骤:
1. 定义
LoadAndAdd
函数,用于从文件中读取第一个名字并添加到列表中(若不存在)。
2. 在
main
函数中,创建女孩和男孩名字的列表。
3. 遍历1900年到2012年,读取每年的女孩和男孩名字文件。
4. 调用
LoadAndAdd
函数处理每个文件。
5. 显示至少有一年最受欢迎的女孩和男孩名字。
8. 拼写检查
找出文件中所有拼写错误的单词,代码如下:
from only_words import onlyTheWords
import sys
WORDS_FILE = "../Data/words.txt"
if len(sys.argv) != 2:
print("One command line argument must be provided.")
print("Quitting...")
quit()
try:
inf = open(sys.argv[1], "r")
except:
print("Failed to open ’%s’ for reading. Quitting..." % sys.argv[1])
quit()
valid = {}
words_file = open(WORDS_FILE, "r")
for word in words_file:
word = word.lower().rstrip()
valid[word] = 0
words_file.close()
misspelled = []
for line in inf:
words = onlyTheWords(line)
for word in words:
if word.lower() not in valid and word not in misspelled:
misspelled.append(word)
inf.close()
if len(misspelled) == 0:
print("No words were misspelled.")
else:
print("The following words are misspelled:")
for word in misspelled:
print(" ", word)
操作步骤:
1. 检查命令行参数是否只包含一个文件名。
2. 尝试打开要检查的文件。若打开失败,显示错误信息并退出。
3. 从字典文件中读取所有有效单词,存储在字典中。
4. 逐行读取要检查的文件,去除标点符号,检查每个单词是否拼写错误。
5. 将拼写错误的单词添加到列表中。
6. 关闭文件。
7. 若没有拼写错误的单词,显示相应信息;否则,显示所有拼写错误的单词。
9. 文件内容脱敏
对文本文件进行脱敏处理,移除所有敏感词,将脱敏后的文本写入新文件,代码如下:
inf_name = input("Enter the name of the text file to redact: ")
inf = open(inf_name, "r")
sen_name = input("Enter the name of the sensitive words file: ")
sen = open(sen_name, "r")
words = []
line = sen.readline()
while line != "":
line = line.rstrip()
words.append(line)
line = sen.readline()
sen.close()
outf_name = input("Enter the name for the new redacted file: ")
outf = open(outf_name, "w")
line = inf.readline()
while line != "":
for word in words:
line = line.replace(word, "*" * len(word))
outf.write(line)
line = inf.readline()
inf.close()
outf.close()
操作步骤:
1. 读取要脱敏的文本文件名并打开文件。
2. 读取敏感词文件名并打开文件,将所有敏感词存储在列表中。
3. 关闭敏感词文件。
4. 读取输出文件名并打开输出文件。
5. 逐行读取要脱敏的文件,将所有敏感词替换为相应数量的星号。
6. 将修改后的行写入输出文件。
7. 关闭输入和输出文件。
10. 查找缺少注释的函数
查找Python文件中没有紧跟注释的函数名,代码如下:
from sys import argv
if len(argv) == 1:
print("At least one filename must be provided as a command line argument.")
print("Quitting...")
quit()
for fname in argv[1 : len(argv)]:
try:
inf = open(fname, "r")
prev = " "
lnum = 1
for line in inf:
if line.startswith("def ") and prev[0] != "#":
bracket_pos = line.index("(")
name = line[4 : bracket_pos]
print("%s line %d: %s" % (fname, lnum, name))
prev = line
lnum = lnum + 1
inf.close()
except:
print("A problem was encountered with file ’%s’." % fname)
print("Moving on to the next file...")
操作步骤:
1. 检查是否提供了至少一个文件名。
2. 遍历所有文件名,尝试打开文件。
3. 逐行读取文件,记录上一行内容和行号。
4. 若当前行是函数定义且上一行不是注释,提取函数名并显示相关信息。
5. 保存当前行并更新行号。
6. 关闭文件。若出现异常,显示错误信息并继续处理下一个文件。
下面是一个简单的流程图,展示了显示文件头部的流程:
graph TD;
A[开始] --> B[检查命令行参数];
B -- 参数错误 --> C[显示错误信息并退出];
B -- 参数正确 --> D[尝试打开文件];
D -- 打开失败 --> C;
D -- 打开成功 --> E[逐行读取文件];
E -- 读取行数小于10且未到文件末尾 --> F[显示当前行];
F --> E;
E -- 读取行数达到10或到文件末尾 --> G[关闭文件];
G --> H[结束];
以上就是这些Python编程问题的详细解决方案,希望对大家有所帮助。在实际应用中,可以根据具体需求对代码进行调整和优化。
Python编程:文件、异常与递归问题的解决方案
11. 递归求和
计算用户输入数字的总和,用户输入空行表示结束输入,代码如下:
def readAndTotal():
line = input("Enter a number (blank to quit): ")
if line == "":
return 0
else:
return float(line) + readAndTotal()
def main():
total = readAndTotal()
print("The total of all those values is", total)
main()
操作步骤:
1. 定义
readAndTotal
函数,在函数内部读取用户输入。
2. 若用户输入为空行,返回 0 作为基本情况。
3. 若输入不为空行,将输入转换为数字并与递归调用
readAndTotal
函数的结果相加。
4. 在
main
函数中调用
readAndTotal
函数得到总和并显示。
12. 递归判断回文串
判断用户输入的字符串是否为回文串,代码如下:
def isPalindrome(s):
if len(s) <= 1:
return True
return s[0] == s[len(s) - 1] and isPalindrome(s[1 : len(s) - 1])
def main():
line = input("Enter a string: ")
if isPalindrome(line):
print("That was a palindrome!")
else:
print("That is not a palindrome.")
main()
操作步骤:
1. 定义
isPalindrome
函数,若字符串长度小于等于 1,返回
True
作为基本情况。
2. 若字符串长度大于 1,检查首尾字符是否相等,若相等则递归调用
isPalindrome
函数检查去掉首尾字符后的子串。
3. 在
main
函数中读取用户输入的字符串,调用
isPalindrome
函数进行判断并显示结果。
13. 计算字符串编辑距离
计算两个字符串之间的编辑距离,编辑距离是将一个字符串转换为另一个字符串所需的最少插入、删除和替换操作次数,代码如下:
def editDistance(s, t):
if len(s) == 0:
return len(t)
elif len(t) == 0:
return len(s)
else:
cost = 0
if s[len(s) - 1] != t[len(t) - 1]:
cost = 1
d1 = editDistance(s[0 : len(s) - 1], t) + 1
d2 = editDistance(s, t[0 : len(t) - 1]) + 1
d3 = editDistance(s[0 : len(s) - 1] , t[0 : len(t) - 1]) + cost
return min(d1, d2, d3)
def main():
s1 = input("Enter a string: ")
s2 = input("Enter another string: ")
print("The edit distance between %s and %s is %d." % (s1, s2, editDistance(s1, s2)))
main()
操作步骤:
1. 定义
editDistance
函数,若其中一个字符串为空,编辑距离为另一个字符串的长度。
2. 若两个字符串都不为空,检查最后一个字符是否相等,若不相等则
cost
设为 1。
3. 递归计算三种可能的编辑距离(删除、插入、替换)。
4. 返回三种距离中的最小值。
5. 在
main
函数中读取用户输入的两个字符串,调用
editDistance
函数计算编辑距离并显示结果。
14. 查找元素最长序列
找出以用户输入元素开头的最长元素序列,序列中每个元素的首字母与前一个元素的尾字母相同,代码如下:
ELEMENTS_FNAME = "../Data/Elements.csv"
def longestSequence(start, words):
if start == "":
return []
best = []
last_letter = start[len(start) - 1].lower()
for i in range(0, len(words)):
first_letter = words[i][0].lower()
if first_letter == last_letter:
candidate = longestSequence(words[i], words[0 : i] + words[i + 1 : len(words)])
if len(candidate) > len(best):
best = candidate
return [start] + best
def loadNames():
names = []
inf = open(ELEMENTS_FNAME, "r")
for line in inf:
line = line.rstrip()
parts = line.split(",")
names.append(parts[2])
inf.close()
return names
def main():
names = loadNames()
start = input("Enter the name of an element: ")
start = start.capitalize()
if start in names:
names.remove(start)
sequence = longestSequence(start, names)
print("A longest sequence that starts with", start, "is:")
for element in sequence:
print(" ", element)
else:
print("Sorry, that wasn’t a valid element name.")
main()
操作步骤:
1. 定义
loadNames
函数,从文件中读取所有元素名称并存储在列表中。
2. 定义
longestSequence
函数,若起始元素为空,返回空列表作为基本情况。
3. 遍历所有元素,若元素首字母与起始元素尾字母相同,递归调用
longestSequence
函数查找以该元素开头的最长序列。
4. 选择最长的候选序列并返回,将起始元素添加到序列开头。
5. 在
main
函数中调用
loadNames
函数加载元素名称,读取用户输入的起始元素。
6. 若输入元素有效,从列表中移除该元素,调用
longestSequence
函数查找最长序列并显示。
7. 若输入元素无效,显示错误信息。
15. 递归扁平化列表
使用递归将可能包含嵌套列表的列表扁平化,代码如下:
def flatten(data):
if data == []:
return []
if type(data[0]) == list:
return flatten(data[0]) + flatten(data[1:])
else:
return [data[0]] + flatten(data[1:])
def main():
print(flatten([1, [2, 3], [4, [5, [6, 7]]], [[[8], 9], [10]]]))
print(flatten([1, [2, [3, [4, [5, [6, [7, [8, [9, [10]]]]]]]]]]))
print(flatten([[[[[[[[[[1], 2], 3], 4], 5], 6], 7], 8], 9], 10]))
print(flatten([1, 2, 3, 4, 5, 6, 7, 8, 9, 10]))
print(flatten([]))
main()
操作步骤:
1. 定义
flatten
函数,若列表为空,返回空列表作为基本情况。
2. 若列表第一个元素是列表,递归调用
flatten
函数将第一个元素和剩余元素分别扁平化并合并。
3. 若列表第一个元素不是列表,将第一个元素添加到递归调用
flatten
函数处理剩余元素的结果前面。
4. 在
main
函数中调用
flatten
函数对不同的嵌套列表进行测试并打印结果。
16. 递归游程编码
对字符串或列表进行游程编码,代码如下:
def encode(data):
if len(data) == 0:
return []
index = 1
while index < len(data) and data[index] == data[index - 1]:
index = index + 1
current = [data[0], index]
return current + encode(data[index : len(data)])
def main():
s = input("Enter some characters: ")
print("When those characters are run-length encoded, the result is:", encode(s))
main()
操作步骤:
1. 定义
encode
函数,若输入为空,返回空列表作为基本情况。
2. 找到第一个与第一个元素不同的元素的索引。
3. 将第一个元素和其连续出现的次数作为当前编码项。
4. 递归调用
encode
函数处理剩余元素并将结果与当前编码项合并。
5. 在
main
函数中读取用户输入的字符串,调用
encode
函数进行游程编码并显示结果。
下面是一个简单的流程图,展示了递归判断回文串的流程:
graph TD;
A[开始] --> B[输入字符串];
B --> C[判断字符串长度是否小于等于1];
C -- 是 --> D[返回True];
C -- 否 --> E[检查首尾字符是否相等];
E -- 否 --> F[返回False];
E -- 是 --> G[递归调用判断子串];
G --> C;
D --> H[结束];
F --> H;
为了更清晰地对比这些不同的功能,下面给出一个简单的表格:
| 功能 | 关键函数 | 主要操作 |
| ---- | ---- | ---- |
| 递归求和 |
readAndTotal
| 递归读取用户输入并累加 |
| 递归判断回文串 |
isPalindrome
| 递归检查字符串首尾字符并处理子串 |
| 计算字符串编辑距离 |
editDistance
| 递归计算三种编辑操作的最小距离 |
| 查找元素最长序列 |
longestSequence
| 递归查找以元素开头的最长序列 |
| 递归扁平化列表 |
flatten
| 递归处理嵌套列表 |
| 递归游程编码 |
encode
| 递归处理字符串或列表进行编码 |
通过以上这些解决方案,我们可以看到递归在解决复杂问题时的强大能力。同时,文件操作和异常处理也为我们处理数据和应对各种情况提供了有效的手段。在实际编程中,我们可以根据具体需求灵活运用这些方法,提高代码的效率和健壮性。希望这些内容能帮助大家更好地掌握 Python 编程中的文件、异常和递归相关知识。
超级会员免费看
1979

被折叠的 条评论
为什么被折叠?



