上一个方式,虽然能获取到标准答案和所对应的学生答案,但代码不够简单和优雅。
这时,可以用另一种方式来实现:遍历索引。
定义
简单来说,enumerate()函数用来遍历一个可遍历对象中的元素,同时通过一个计数器变量记录当前元素所对应的索引值。
比如刚才的代码中:
存储标准答案的列表standardTwo可以作为可遍历的对象;
而记录学生答案的索引idx则可以看作是用于计数的变量。
enumerate()函数常用于for循环中。当我们既需要一个计数器,又需要可遍历对象的值时,就可以使用enumerate()函数。接下来,我们来看看它的具体用法~
enumerate()函数需要传入一个必选参数:任意可遍历的数据对象。 |
# 使用import导入os模块 import os # 使用import导入docx import docx # 第二大题填空题标准答案 standardTwo = ["东临碣石", "行舟绿水前", "孤山寺北贾亭西", "断肠人在天涯", "故人具鸡黍", "一曲新词酒一杯", "何当共剪西窗烛", "误入藕花深处", "烟笼寒水月笼沙", "万籁此都寂", "初日照高林", "腾蛇乘雾"]
# 将乔老师的答题卡文件夹路径 /Users/qiao/answerKey 赋值给变量allKeyPath allKeyPath = "/Users/qiao/answerKey" # 使用os.listdir()函数获取该路径下所有的文件,并赋值给变量allItems allItems = os.listdir(allKeyPath) # 定义一个空列表allStudentsData存储所有学生数据 allStudentsData = [] # 使用for循环逐个遍历所有学生答题卡 for item in allItems: # 定义一个空字典studentData存储单个学生数据 studentData = {}
# 使用os.path.splitext()函数获取文件名的前半段,并赋值给变量fileName fileName = os.path.splitext(item)[0] # 使用split()函数以"-"分隔文件名,将第1部分班级信息赋值到学生数据字典的classInfo键里 studentData["classInfo"] = fileName.split("-")[0] # 使用split()函数以"-"分隔文件名,将第2部分姓名信息赋值到学生数据字典的name键里 studentData["name"] = fileName.split("-")[1]
# 使用os.path.join()函数拼接出答题卡路径,并赋值给变量keyPath keyPath = os.path.join(allKeyPath, item) # 读取答题卡并赋值给变量doc doc = docx.Document(keyPath)
# 读取第四段学号段,并赋值给变量idPara idPara = doc.paragraphs[3] # 读取学号段中第二个样式块,并赋值给变量idRun idRun = idPara.runs[1] # 读取学号,并赋值到学生数据字典的id键里 studentData["id"] = idRun.text
# 使用for循环和enumerate()函数,遍历standardTwo for idx,value in enumerate(standardTwo): # 格式化输出:索引值n所对应的列表元素是xxx print(f"索引值{idx}所对应的列表元素是{value}") # 使用append()函数 # 将studentData添加到总学生数据allStudentsData中 allStudentsData.append(studentData) |
根据输出可以看到:
这个循环遍历了standardTwo列表的所有元素,元素存储在变量value中。
同时,有一个从零开始增加的计数器idx,来记录每个元素对应的索引。
idx默认从0开始,到11结束,这是因为standardTwo这个列表一共只有12个元素。
再来对比一下: |
我们已经能在遍历标准答案列表的同时,拥有一个能自动累加的计数器。可以直接根据这个计数器,来访问答题卡里学生的填空题答案。
可是现在计数器是从0开始的,而填空题答案从第9段开始,对应的段落索引是8,有什么办法能让计数器从8开始逐一增加呢?
修改起始索引 要设置索引的初始值,可以直接将初始值作为可选参数传入enumerate()函数中。 |
# 使用import导入os模块 import os # 使用import导入docx import docx # 第二大题填空题标准答案 standardTwo = ["东临碣石", "行舟绿水前", "孤山寺北贾亭西", "断肠人在天涯", "故人具鸡黍", "一曲新词酒一杯", "何当共剪西窗烛", "误入藕花深处", "烟笼寒水月笼沙", "万籁此都寂", "初日照高林", "腾蛇乘雾"]
# 将乔老师的答题卡文件夹路径 /Users/qiao/answerKey 赋值给变量allKeyPath allKeyPath = "/Users/qiao/answerKey" # 使用os.listdir()函数获取该路径下所有的文件,并赋值给变量allItems allItems = os.listdir(allKeyPath) # 定义一个空列表allStudentsData存储所有学生数据 allStudentsData = [] # 使用for循环逐个遍历所有学生答题卡 for item in allItems: # 定义一个空字典studentData存储单个学生数据 studentData = {}
# 使用os.path.splitext()函数获取文件名的前半段,并赋值给变量fileName fileName = os.path.splitext(item)[0] # 使用split()函数以"-"分隔文件名,将第1部分班级信息赋值到学生数据字典的classInfo键里 studentData["classInfo"] = fileName.split("-")[0] # 使用split()函数以"-"分隔文件名,将第2部分姓名信息赋值到学生数据字典的name键里 studentData["name"] = fileName.split("-")[1]
# 使用os.path.join()函数拼接出答题卡路径,并赋值给变量keyPath keyPath = os.path.join(allKeyPath, item) # 读取答题卡并赋值给变量doc doc = docx.Document(keyPath)
# 读取第四段学号段,并赋值给变量idPara idPara = doc.paragraphs[3] # 读取学号段中第二个样式块,并赋值给变量idRun idRun = idPara.runs[1] # 读取学号,并赋值到学生数据字典的id键里 studentData["id"] = idRun.text
# 使用for循环和enumerate()函数 # 遍历储存标准答案的列表standardTwo的同时 # 生成一个从8开始的index for idx,value in enumerate(standardTwo,8): # 格式化输出:索引值n所对应的列表元素是xxx print(f"索引值{idx}所对应的列表元素是{value}") # 使用append()函数 # 将studentData添加到总学生数据allStudentsData中 allStudentsData.append(studentData) |
enumerate()函数的必选参数 可迭代的对象,示例中是一个列表,该列表存储了填空题的标准答案。 |
存储列表的元素 value用于在for循环里,存储遍历时standardTwo中的元素。 |
存储索引值 idx相当于一个计数器变量,用于在for循环里,记录standardTwo里各元素所对应的索引值。 |
# 使用import导入os模块 import os # 使用import导入docx import docx # 第二大题填空题标准答案 standardTwo = ["东临碣石", "行舟绿水前", "孤山寺北贾亭西", "断肠人在天涯", "故人具鸡黍", "一曲新词酒一杯", "何当共剪西窗烛", "误入藕花深处", "烟笼寒水月笼沙", "万籁此都寂", "初日照高林", "腾蛇乘雾"]
# 将乔老师的答题卡文件夹路径 /Users/qiao/answerKey 赋值给变量allKeyPath allKeyPath = "/Users/qiao/answerKey" # 使用os.listdir()函数获取该路径下所有的文件,并赋值给变量allItems allItems = os.listdir(allKeyPath) # 定义一个空列表allStudentsData存储所有学生数据 allStudentsData = [] # 使用for循环逐个遍历所有学生答题卡 for item in allItems: # 定义一个空字典studentData存储单个学生数据 studentData = {}
# 使用os.path.splitext()函数获取文件名的前半段,并赋值给变量fileName fileName = os.path.splitext(item)[0] # 使用split()函数以"-"分隔文件名,将第1部分班级信息赋值到学生数据字典的classInfo键里 studentData["classInfo"] = fileName.split("-")[0] # 使用split()函数以"-"分隔文件名,将第2部分姓名信息赋值到学生数据字典的name键里 studentData["name"] = fileName.split("-")[1]
# 使用os.path.join()函数拼接出答题卡路径,并赋值给变量keyPath keyPath = os.path.join(allKeyPath, item) # 读取答题卡并赋值给变量doc doc = docx.Document(keyPath)
# 读取第四段学号段,并赋值给变量idPara idPara = doc.paragraphs[3] # 读取学号段中第二个样式块,并赋值给变量idRun idRun = idPara.runs[1] # 读取学号,并赋值到学生数据字典的id键里 studentData["id"] = idRun.text
# 使用for循环和enumerate()函数 # 遍历储存标准答案的列表standardTwo的同时 # 生成一个从8开始的idx for idx,value in enumerate(standardTwo, 8): # 格式化输出:索引值n所对应的列表元素是xxx print(f"索引值{idx}所对应的列表元素是{value}") # 使用append()函数 # 将studentData添加到总学生数据allStudentsData中 allStudentsData.append(studentData) |
第一个for循环 第一个for循环,也就是最外层的for循环,是在遍历allItems中所有的学生答题卡。 |
第二个for循环 第二个for循环在第一个for循环里,用于遍历当前同学的填空题答案和对应的标准答案。 |
总结: