Python 基础练习3¶
用户输入——示例¶
请把最后一行 run_adder
从注释拿出来,这样才能运行这段代码。
# 我们定义一个加法计算器
def run_adder():
total = 0
while True:
user_input = input("请输入下一个数。输入 'stop' 停止。")
if user_input == "stop":
break # break 语句会退出当前的循环(如果是多层循环的话只会跳出一层循环)
x = float(user_input) # 这一句可能会导致问题,比如当用户的输入包含字母
total = total + x
print(total)
# run_adder()
你会发现,好不容易输入了一大堆数字,一不小心输入一个字母,程序就崩溃,之前累加的数值就全白费了。
所以需要在 float(user_input)
这一句之前,判断一下用户输入到底能不能被转换成数字。
正则表达式——示例¶
注意,我们会用 \
来对一些特殊字符进行 转义
,来去掉它们的特殊含义。
比如 .
在表达式中是 通配符
的意思,会匹配任何字符。加上斜杠后,就退化成字面上的 .
。
import re
third_decimals = ["3.142", "123.456", "125135316235623.123", "0.456"] # 精确到三位小数的数字
non_third_decimals = ["12", "1.234567", "abc", "123a.133", "ba12"] # 所有其它的字符串
expression = "^[0-9]*\.[0-9]{3}$" # 注意 '*' 后面的 '\.'这个斜杠是必要的,因为 `.` 是一个有特殊含义的字符,就和 `[` 一样
# 不是真的去匹配 `[` 这个字符。这种有特殊含义的字符前面需要加上斜杠来进行 `转义`。
for string in third_decimals:
print(bool(re.search(expression, string)))
print("以上全部为 True")
for string in non_third_decimals:
print(bool(re.search(expression, string)))
print("以上全部为 False")
请把最后一行 run_adder_safe
从注释拿出来,这样才能运行这段代码。
# 我们定义一个安全的加法计算器
integer_expression = "^[0-9]{1,}$"
def run_adder_safe():
total = 0
while True:
user_input = input("请输入下一个数。输入 'stop' 停止。")
if user_input == "stop":
break
if not re.search(integer_expression, user_input):
print("输入不合法!")
continue # continue 可以直接结束当前这一轮的循环,进入下一轮。
# 因为输入不合法,所以直接重新来一轮循环,从而跳过了下面那句会出错的句子。
x = float(user_input)
total = total + x
print("当前总和: " + str(total))
print(total)
# run_adder_safe()
正则表达式——练习¶
valid_sort_code = ["24-12-45", "55-34-12", "00-00-11", "55-66-77"] # 合法的 sort code(英国银行卡上用的)
invalid_sort_code = ["aa-22-33", "11 22 33", "15t23g", "314159", "a1-b2-c3"] # 所有其它的字符串
expression = "" # 在这里写表达式!
for string in valid_sort_code:
print(bool(re.search(expression, string)))
print("以上全部为 True")
for string in invalid_sort_code:
print(bool(re.search(expression, string)))
print("以上全部为 False")
更多练习请点击这里!
用户输入和正则匹配——练习¶
# 先读取用户输入数字,再读取 '+', '-', '*', '/' 四种字符中的一个
# 然后像计算器那样进行运算,直到用户输入 `stop`
# 注意使用正则表达式检查用户输入是否合法
# 如果觉得困难,就只允许整数。喜欢挑战的话可以尝试一下匹配浮点数。
import re
def run_calculator():
while None:
return None
def isValidNumber(user_input):
return False
def isValidOp(user_input):
return False
run_calculator()
字典——示例¶
x = dict()
x["abc"] = 10
x["bcd"] = 20
x["cde"] = 30
print(x.keys())
print(x.values())
print(x.items())
x["abc"] = 100
print(x.values())
print(20 in x.values())
print(200 in x.values())
print("abcd" in x.keys())
文本处理——示例¶
我们先下载一下《红楼梦》这本书。下面的代码之后要求大家都会写,现在可以先跳过。
# 这一段代码请复制到本地运行,拿到我们需要处理的文本。
# 有兴趣的同学可以研究一下它做了啥。
# 不想看的同学可以先跳过。
# 不过这种代码之后要求会写的。
# 总之就是自动从服务器下载了一个 txt 文件。
import requests
import os
dir_path = 'txt_files'
file_name = 'hongloumeng.txt'
full_path = os.path.join(dir_path, file_name)
if not os.path.exists(dir_path):
os.mkdir(dir_path)
if not os.path.exists(full_path):
url = "http://icewould.com/m5-101/hongloumeng"
print("正在下载文件...")
result = requests.get(url)
with open(full_path, "wb") as f:
f.write(result.content)
print("下载完成")
# 读取文件
lines = None
with open('./txt_files/hongloumeng.txt', 'r', encoding = 'utf-8') as f:
lines = f.readlines()
print(lines[:3]) # 看一下前 3 个段落
print()
print("全书一共 " + str(len(lines)) + " 个段落") # 看一下全书一共有多少段落
content = "".join(lines) # lines 是一个数组,每一个元素是一个段落。现在把它完整拼起来,成为一整个字符串,存放在 content 变量里。
print("全书一共 " + str(len(content)) + " 个字符")
通过字典,我们来统计一下,每一个字出现的次数。
大家可以把最后的 print
从注释里拿出来,打印一下看看。
counter = dict()
for character in content:
if not character in counter.keys():
counter[character] = 1
else:
counter[character] = counter[character] + 1
# print(counter)
其实,可以直接使用 Python
自带的 Counter
进行统计,但是为了让大家熟练掌握 Dictionary
的用法,还是建议大家先自己手写。
然后,我们看看《红楼梦》中,贾xx
或者 贾x
字符串共出现了多少次。
import re
expression = "贾[\u4e00-\u9fa5]{1,2}"
result = re.findall(expression, content)
print(len(result))
好奇它们都是啥么?我们打印出前几个看一下。
print(result[:100])
注意,这些不都是人名哦,比如 贾政便
。
要提取出姓贾的人名,可能需要一番功夫了。
此外,我们可以把重复的删去。这里要用到 set
这个数据结构,有兴趣的同学可以去搜一下 python set
。set
其实就是数学里的 集合
,它不允许有重复的元素。
print(set(result[:100]))
一共有多少个不重复的呢?
print(len(set(result)))
文本处理——练习¶
练习1¶
请把我们的《红楼梦》文本中所有不是汉字的东西去掉
匹配所有非汉字的正则表达式是:
[^\u4e00-\u9fa5]
匹配所有汉字的正则表达式是:
[\u4e00-\u9fa5]
请先不要看以下代码,自己尝试一下。提示,使用 re.sub
函数以及 ""
(空字符串)来替换,达到删除的效果。
# 请遮住以下代码,自己先写
import re
def clear_content(content):
expression = '[^\u4e00-\u9fa5]'
result = re.sub(expression, "", content)
return result
result = clear_content(content)
print(result[:300]) # 展示处理完毕后的前 300 个字
练习2¶
请统计《红楼梦》中出现次数最多的汉字(注意,请先把标点符号去除掉)
练习 3¶
请统计《红楼梦》中出现次数最多的前三个汉字。
练习 4¶
请统计《红楼梦》中,黛玉与宝玉两个人名在相隔 20 字内同时出现的次数。