【头歌-Python】字符串自学引导

禁止转载,原文:https://blog.csdn.net/qq_45801887/article/details/137517279
参考教程:B站视频讲解——https://space.bilibili.com/3546616042621301

第1关:统计“唐诗三百首”中诗人出现的次数

任务描述
本关任务:编写一个能统计“唐诗三百首”中诗人出现次数的小程序。

相关知识
为了完成本关任务,你需要掌握:

  1. 序列元素计数方法

序列元素计数方法
s.count(x)可以返回序列s中元素x出现的次数。

txt = '武汉市有武汉大学、武汉理工大学、武汉科技大学等学校大量招收武汉学生'
print(txt.count('武汉'))  # 输出字符串中“武汉”出现的次数

输出:

5

文件’唐诗三百首.txt’中包含唐代诗人的300首左右的诗歌。各关会给出将文件读取为一个字符串和将文件逐行读取为字符串的方法,我们需要用字符串的方法对其进行处理,完成各关的任务。

编程要求
根据提示,在右侧编辑器补充代码,接收用户输入的一个诗人名字,统计并输出文件中该名字出现的次数(包括以作者身份出现和在诗句中出现),题目的测试数据保证都是文件中存在的诗人名字。
7.8 宋词三百首.txt
唐诗三百首 (2022).txt(下载后按题目要求修改文件名)

测试说明
平台会对你编写的代码进行测试:

测试输入:

李白

预期输出:

33

测试输入:

杜甫

预期输出:

37

开始你的任务吧,祝你成功!

参考代码

# 禁止转载,原文:https://blog.csdn.net/qq_45801887/article/details/137517279
def count_poet(file, poet):
    """统计诗人出现的次数,包括以作者身份和出现的诗句中的情况,返回一个整数"""
    with open(file, 'r', encoding='utf-8') as fr:
        txt = fr.read()  # 读取全部内容为一个字符串,此句不用理解,只需知道txt是包含所有诗句的字符串即可
    # 对齐此位置写程序语句,统计并返回诗人在字符串中出现的次数
        return txt.count('{}'.format(poet_name))
        

if __name__ == '__main__':
    filename = '/data/bigfiles/唐诗三百首.txt'  # 文件名
    poet_name = input()                        # 输入诗人的名字
    print(count_poet(filename, poet_name))     # 调用函数统计并输出诗人在字符串中出现的次数

第2关:统计文件中汉字字数

任务描述
本关任务:编写一个能统计文件里去除标点后的汉字字数的小程序。

相关知识
为了完成本关任务,你需要掌握:

  1. 字符串替换方法
  2. 字符数量

字符串替换方法
txt.replace(a, b)可以将字符串txt中的子字符串a替换为字符串b,若需重复替换操作,一般应该重用字符串名,例如:

txt = 'one1two2three3four4five5six6seven7eight8nine9ten10'
for c in '0123456789':       # 遍历需要替换的数字
    txt = txt.replace(c, ' ')  # 将数字等字符替换为空格字符串,下一次替换在前一次替换结果的基础上进行
print(txt)

输出:

one two three four five six seven eight nine ten 
txt = 'one1two2three3four4five5six6seven7eight8nine9ten10'
for c in '0123456789':       # 遍历需要替换的数字
    txt = txt.replace(c, '')  # 将数字等字符替换为空字符串,下一次替换在前一次替换结果的基础上进行
print(txt)

输出:

onetwothreefourfivesixseveneightnineten

字符数量
len()函数可以返回序列x的中的元素个数,作用于字符串时,返回字符串的长度,即字符串中字符数量:

txt = 'one two three four five six seven eight nine ten'
print(len(txt))

输出

48
txt = 'onetwothreefourfivesixseveneightnineten'
print(len(txt))

输出:

39

编程要求
根据提示,在右侧编辑器补充代码,接收用户输入的一个文件名字,模板程序提供了将文件读取为字符串的语句,请将字符串中标点符号和数字等符号去除,统计并输出文件汉字数量(需去除的标点与符号包括:',【】[[],、 —《》() >~-·。:!?\n\r\t0123456789')。

测试说明
平台会对你编写的代码进行测试:

测试输入:

唐诗三百首.txt

预期输出:

21244

提示:

  1. 另一个测试点是其他文件
  2. 需要替换掉的字符:',【】[[],、 —《》() >~-·。:!?\n\r\t0123456789'

开始你的任务吧,祝你成功!

参考代码

# 禁止转载,原文:https://blog.csdn.net/qq_45801887/article/details/137517279
def count_words(file):
    """替换掉全部全角' '与半角空格' ',标点符号,换行符和数字字符,使用下面的字符串:
    ',【】[[],、 —《》() >~-·。:!?\n\r\'0123456789'
    统计字数"""
    with open(file, 'r', encoding='utf-8') as fr:
        txt = fr.read()  # 读取全部内容为一个字符串,此句不用理解,只需知道txt是包含所有诗句的字符串即可
    # 对齐此位置补充代码,替换掉指定的字符并返回包含汉字的数量
        b="',【】[[],、 —《》() >~-·。:!?\n\r\t0123456789')"
        for i in b:
            if i in txt:
                txt=txt.replace(i,'')
            
        return len(txt)
    
if __name__ == '__main__':
    filename = input()  # 输入文件名字
    print(count_words('/data/bigfiles/' + filename))

第3关:格式化输出全部诗名

任务描述
本关任务:编写一个能输出唐诗三百首中作者与诗名的小程序。

相关知识
为了完成本关任务,你需要掌握:

  1. 遍历文件对象
  2. 字符串索引切片
  3. 去除字符串首尾字符
  4. 字符串切分
  5. 字符串格式化

遍历文件对象
创建文件对象后可以用for...in 文件对象的方法遍历文件,每次循环依次获得文件对象中的一行,字符串名类型,行末有一个换行符'\n'

with open('唐诗三百首.txt', 'r', encoding='utf-8') as fr:
    for line in fr:   # 遍历文件对象,line为当前行,字符串
        print(line)  # 输出当前字符串

输出:

`...
045孟郊:游子吟

慈母手中线,游子身上衣。

临行密密缝,意恐迟迟归。

谁言寸草心,报得三春辉?
...
` 

字符串索引切片
txt[i]可以返回字符串txt的中序号为i的字符

txt = '079李白:蜀道难\n'  # 序号0,1,2的字符分别是0,7,9
print(txt[0])

输出

0

索引不能越界,空字符串不能索引。

s = ''
print(s[0])      # IndexError: string index out of range

txt[m: n]可以返回字符串txt的中序号为从m到n(不包括n)之间的字符

txt = '079李白:蜀道难\n'  # 序号0,1,2的字符分别是0,7,9
print(txt[:3])

输出:

079

切片结果可以为空,起止值可以越界,空字符串可以切片。

s = ''
print(s[0:4])    # ''  返回空字符串
print([s[0:4]])  # ['']转为列表可直观查看

去除字符串首尾字符
txt.strip()可以去除字符串txt的开头结果的空白字符,如换行符’\n’等
如果想去除字符串首尾的其他字符,可以将要去除的字符做为参数放到括号中。

txt = '079李白:蜀道难\n'
print(txt.strip())

输出

079李白:蜀道难

字符串切分
txt.split(sep)可以根据参数sep将字符串txt切分为包含多个元素的列表

txt = '079李白:蜀道难\n'  # 字符串
print(txt.split(':'))    # 根据全角冒号切分为列表

输出

['079李白', '蜀道难\n']

字符串的方法可以链式应用,前一个方法处理结果若仍是字符串,可以继续应用字符串的方法进行处理,例如:

txt = '079李白:蜀道难\n'  # 字符串
print(txt.strip().split(':'))    # txt.strip()结果仍是字符串,可以继续应用split()方法,先去除末尾的换行符,再切分为列表

输出

['079李白', '蜀道难']

个别诗名中包含冒号:

txt = '039李白:子夜四时歌:春歌\n'  # 字符串
# 根据全角冒号切分为列表,列表中3个对象
print(txt[3:].strip().split(':'))

输出

['李白', '子夜四时歌', '春歌']

在切分时可以加maxsplit=1参数,限制最多切分一次,使诗名完整

txt = '039李白:子夜四时歌:春歌\n'  # 字符串
order_number = txt[:3]    # 标题行字符串前3个字符为序号
poet, poem = txt[3:].strip().split(':', maxsplit=1)
print(f'序号{order_number}的诗是【{poet}】作品“{poem}”')

输出

序号039的诗是【李白】作品“子夜四时歌:春歌”

字符串格式化
str.format()f-string可以对字符串进行格式化,将不改变的字符串放在引号中,将需要改变的变量放到字符串中的大括号{}中或做为format()的参数,程序设计时将用变量值填充在大括号所占的位置。

txt = '079李白:蜀道难\n'  # 字符串
order_number = txt[:3]    # 标题行字符串前3个字符为序号
# 标题行字符串第4个字符以后的部分根据全角冒号切分为列表,列表中2个对象分别命名为poet, poem
poet, poem = txt[3:].strip().split(':')
print(f'序号{order_number}的诗是【{poet}】作品“{poem}”')

输出

序号079的诗是【李白】作品“蜀道难”

若需要指定输出数据的宽度,可以使用{:宽度(int)}的写法来限定,如:

print(f'序号{order_number}的诗是【{poet:4}】作品“{poem}”')

输出

序号079的诗是【李白  】作品“蜀道难”

作者名长度不足4位则右补空格,超过4位则输出原始数据宽度。

文件’唐诗三百首.txt’中包含唐代诗人的300首左右的诗歌。每首诗前都有类似“079李白:蜀道难”的一行,这行包括序号、用全角冒号分隔开的作者和诗名(有些诗可能会有两个冒号),本关要求输出包含序号、作者和诗名的行。

编程要求
根据提示,在右侧编辑器补充代码,遍历文件对象,按测试用例格式输出包含3位数字序号、作者名和诗歌名。
注意: 作者名长度并不相同,要求以3位固定宽度输出,不足3位的右补空格填充。

测试说明
平台会对你编写的代码进行测试:

预期输出:

序号010的诗是【杜甫 】作品“佳人”
序号011的诗是【杜甫 】作品“梦李白二首之一”
序号012的诗是【杜甫 】作品“梦李白二首之二”
序号013的诗是【王维 】作品“送别”
...
序号034的诗是【柳宗元】作品“晨诣超师院读禅经”
...

开始你的任务吧,祝你成功!

参考代码

# 禁止转载,原文:https://blog.csdn.net/qq_45801887/article/details/137517279

统一说明:第三关没有问题,自己好好看看符号、格式是否正确,目前评论区说过不了的都是自己的原因,再好好检查一下
def get_poem(file):
    """读唐诗三百首,从每首诗的标题行中提取出序号、作者和诗名,输出序号作者与诗名,格式如下:
    序号106的诗是【杜甫】作品“春望”
    """
    with open(file, 'r', encoding='utf-8') as fr:  # 打开文件创建文件对象
        for line in fr:    # 遍历文件,每次循环line依次获取文件的一行,字符串类型,以换行符'\n'结尾
            # 补充你的代码,按要求格式输出全部诗名的信息
            if ":" in line:
                order_number = line[:3]  
                poet, poem = line[3:].strip().split(':', maxsplit=1)
                print(f'序号{order_number}的诗是【{poet:3}】作品“{poem}”')
     
if __name__ == '__main__':
    get_poem('/data/bigfiles/唐诗三百首.txt')   # 调用函数,函数内进行输出

第4关:随机输出一首诗

任务描述
本关任务:编写一个能从唐诗三百首中随机抽取一首诗输出的小程序。

相关知识
为了完成本关任务,你需要掌握:

  1. 获取随机整数
  2. 随机数种子
  3. 字符串拼接
  4. 不超过3位数的整数转3位字符串

获取随机整数
random.randint(a,b)可以随机获得[a,b]之间的一个整数,包含a和b。

import random
number = random.randint(10, 320)
print(number)

输出:

84   # 结果不确定,可为任意10-320之间的整数 

随机数种子
random.seed(n)设置随机数种子后可以使程序运行时产生的随机数固定不变,一般用于自动评测的程序都需要确定随机数种子。

import random
random.seed(50)
number = random.randint(10, 320)
print(number)

输出

264  # 种子值确定后,输出的随机数就固定不变

txt[m: n]可以返回字符串txt的中序号为从m到n(不包括n)之间的字符

txt = '079李白:蜀道难\n'  # 序号0,1,2的字符分别是0,7,9
print(txt[:3])

输出:

079

字符串拼接
+可以将多个字符串拼接为一个字符串,拼接时,字符串可以包含换行符等。

poem = ''           # 空字符串
txt1 = '235杜甫:八阵图\n'
poem = poem + txt1  # 字符串拼接
txt2 = '功盖三分国,名成八阵图。\n'
poem = poem + txt2  # 字符串拼接
txt3 = '江流石不转,遗恨失吞吴。\n'
poem = poem + txt3  # 字符串拼接
print(poem)

输出

235杜甫:八阵图
功盖三分国,名成八阵图。
江流石不转,遗恨失吞吴。

不超过3位数的整数转3位字符串
random.randint(a,b)可能会获取2位的整数,如87,此时若直接用成员判定:

if str(87) in line:

可能会把序号为87、187和287的诗都输出,与我们要求不符。
可以用str.format()f-string方法将整数格式化为3位数字的字符串:

number = 87
print(f'{number:03}')  # 3表示至少用3位表示,不足3位前面补0

输出:

087

文件’唐诗三百首.txt’中包含唐代诗人的300首左右的诗歌。随机抽取其中一首输出。

编程要求
根据提示,在右侧编辑器补充代码,先输入一个整数做随机数种子,抽取一首诗的序号,再遍历文件对象,把抽到的那个序号的诗句拼接为一个字符串再输出。

测试说明
平台会对你编写的代码进行测试:
输入:

50

预期输出:

264王昌龄:芙蓉楼送辛渐

寒雨连江夜入吴,平明送客楚山孤。
洛阳亲友如相问,一片冰心在玉壶。

开始你的任务吧,祝你成功!

参考代码

# 禁止转载,原文:https://blog.csdn.net/qq_45801887/article/details/137517279
# 补充一条语句,导入random库
import random
def random_poem(file, num):
    """接受文件名字符串和一个整数为参数,随机产生一个10-320之间的整数,返回对应序号的诗句,字符串类型 """
    # 补充1条语句,用户输入的整数做随机数种子
    random.seed(n)
    
    # 补充1条语句,获取10-320之间一个整数
    
    i=random.randint(10, 320)
    poem = ''                              # 空字符串,用于容纳目标诗
    poet_flag = False                      # 做一个标记,假定当前行不是目标诗
    with open(file, 'r', encoding='utf-8') as fr:  # 创建文件对象
        for line in fr:                    # 遍历文件对象
            # 补充3条语句,当当前行包含序号(序号用3位数,不足3位前面补0)时,将当前行拼接到poem上,改变poet_flag的值为True
            I=f'{i:03}'
            if I==line[:3]:

                poem = poem + line
                poet_flag = True

            elif line[0] in '0123456789':  # 若当前行不包含序号但有数字
                poet_flag = False          # 改变标记,后续几行不是目标诗句
            elif poet_flag:                # 如果标记值为真(True)
                poem = poem + line         # 将当前行拼接到字符串上
        return poem                        # 遍历结束后返回包含目标诗的字符串
        
if __name__ == '__main__':
    n = int(input())                       # 输入一个整数做随机数种子
    print(random_poem('/data/bigfiles/唐诗三百首.txt', n))

版权声明:本文为博主作者:谛凌原创文章,版权归属原作者,如果侵权,请联系我们删除!

原文链接:https://blog.csdn.net/qq_45801887/article/details/137517279

共计人评分,平均

到目前为止还没有投票!成为第一位评论此文章。

(0)
社会演员多的头像社会演员多普通用户
上一篇 2024年5月6日
下一篇 2024年5月6日

相关推荐