第30讲 第4题 查找关键字的具体位置 为啥我的程序跑不对啊
代码思路我都写在注释里了,为什么跑不出来啊,请各位帮忙看看吧!谢谢大家
主要思路就是:一个文件有关键字,这个文件创一个列表each_txt,列表里放字典line_site,字典的键是行数line_num,值是列数site_num(字符位置)且值site_num也是一个列表(因为有多个位置)
import os
paths = [] # 存放有关键字的文件的路径
each_txt = [] # 存放每个文件中每个关键字{行:列}字典的列表
def search_keyword(keyword) :
all_files = os.listdir(os.curdir)
for each_file in all_files:
ext = os.path.splitext(each_file)
if os.path.isdir(each_file) :
os.chdir(each_file)
search_keyword(keyword)
os.chdir(os.pardir)
if ext == '.txt':
path = os.getcwd() + os.sep + each_file # path保存文本文件路径
f = open(each_file)
line_site = dict() # 存放每个关键字{行:列}的字典,每个新文件都要置空
line_num = 0
for each_line in f:
site_num = [] # 存放【列】的列表,每一行查找时都要置空
line_num += 1 # 每行的行数每次 +1
while 1:
i = 0
site = each_line.find(keyword, i) # 查找关键字,如果有返回关键字的第一个索引号(即列),没有返回-1
if site != -1: # 查到关键字
site_num.append(site)# 将关键字的第一个索引号即列值加入列表中
i = site + 1 # 从site后一个位置查找这一行还有没有关键字(11在1111中的数目
else: # 如果没有找到关键字
break # 说明each_line这一行检索完毕或根本没有关键字,退出while循环查找下一行
if site_num == []: # 如果【列】的列表是空的,说明这一行没有关键字
continue # 继续查找下一行
else: # 如果【列】的列表不是空的,说明这一行有关键字
line_site = site_num# 在字典中添加{行数(数字):列数【列表】}
each_txt.append(line_site) # 在这个文件的列表中添加字典
if line_site == {}: # 如果字典是空的,说明没有{行:列}添加,即此文件中没有关键字
continue # 退出查找每行的for循环,查找下一文件
else: # 如果字典不是空的,说明有{行:列}添加,即此文件中有关键字
paths.append(path) # 添加此文件的路径
f.close()
keyword = input('请将该脚本放于待查找的文件夹内,请输入关键字:')
search_keyword(keyword)
decide = input('请问是否需要打印关键字【%s】在文件中大的具体位置(YES/NO):' % keyword)
if decide in ['YES', 'yes', 'Yes']:
if paths == []: # 为空说明没有存在关键字的文件
print('===================================================')
print('当前文件夹内所有文本文件均不含有此关键字!')
else:
print('===================================================')
for each_path in paths: # paths有一个元素就说明有一个文件有关键字
print('在文件【%s】中找到关键字【%s】' % (each_path, keyword))
for each_line_site in each_txt: # each_txt是一个列表(每个文件一个列表),每个元素each_line_site都为字典
for each_item in each_line_site.items(): # each_item是字典的每一项,是一个元组(键(行),值(列))
print('关键字出现在第 %d 行,第' % each_item(0), each_item(1), '个位置。')# 值(列)是一个列表 这是个死循环:
while 1:
i = 0
site = each_line.find(keyword, i) # 查找关键字,如果有返回关键字的第一个索引号(即列),没有返回-1
if site != -1: # 查到关键字
site_num.append(site)# 将关键字的第一个索引号即列值加入列表中
i = site + 1 # 从site后一个位置查找这一行还有没有关键字(11在1111中的数目
else: # 如果没有找到关键字
break # 说明each_line这一行检索完毕或根本没有关键字,退出while循环查找下一行
i每次循环都初始化为0,所以只要包含关键字,就成了死循环,把i=0放在外面就可以了:
i = 0
while 1:
site = each_line.find(keyword, i) # 查找关键字,如果有返回关键字的第一个索引号(即列),没有返回-1
if site != -1: # 查到关键字
site_num.append(site)# 将关键字的第一个索引号即列值加入列表中
i = site + 1 # 从site后一个位置查找这一行还有没有关键字(11在1111中的数目
else: # 如果没有找到关键字
break # 说明each_line这一行检索完毕或根本没有关键字,退出while循环查找下一行
顺便说一下,测试的时候碰到编码错,批量处理文本文件的时候难免碰到编码不同的文件,可以参考这个帖子改一下代码:避免打开文本文件出现编码错误的一个小技巧 txxcat 发表于 2020-4-22 18:52
这是个死循环:
i每次循环都初始化为0,所以只要包含关键字,就成了死循环,把i=0放在外面就可以了:
您好 我按照您说的修改了
但是结果还是有点问题
运行结果是:
请将该脚本放于待查找的文件夹内,请输入关键字:of
请问是否需要打印关键字【of】在文件中大的具体位置(YES/NO):yes
===================================================
在文件【F:\Python\JupyterProject\猪猪大数据\city.txt】中找到关键字【of】
关键字出现在第 3 行,第 个位置。
关键字出现在第 7 行,第 个位置。
关键字出现在第 3 行,第 个位置。
关键字出现在第 7 行,第 个位置。
关键字出现在第 17 行,第 个位置。
===================================================
在文件【F:\Python\JupyterProject\面朝大海,春暖花开.txt】中找到关键字【of】
关键字出现在第 3 行,第 个位置。
关键字出现在第 7 行,第 个位置。
关键字出现在第 3 行,第 个位置。
关键字出现在第 7 行,第 个位置。
关键字出现在第 17 行,第 个位置。
第3行和第7行是第一个文件的,打印了两次
第17行是第二个文件的 本帖最后由 txxcat 于 2020-4-24 01:58 编辑
yangxuebabe 发表于 2020-4-23 22:00
您好 我按照您说的修改了
但是结果还是有点问题
你的代码还有几处错误,看注释:
import os
paths = [] # 存放有关键字的文件的路径
each_txt = [] # 存放每个文件中每个关键字{行:列}字典的列表
def copen(filename):
try:
f = open(filename,encoding='GBK')
try:
f.read()
f.seek(0)
except UnicodeDecodeError:
f = open(filename,encoding='utf-8',errors='ignore')
except (OSError,AttributeError) as reason:
print(str(reason))
return None
return f
def search_keyword(keyword) :
all_files = os.listdir(os.curdir)
for each_file in all_files:
ext = os.path.splitext(each_file)
if os.path.isdir(each_file) :
os.chdir(each_file)
search_keyword(keyword)
os.chdir(os.pardir)
if ext == '.txt':
path = os.getcwd() + os.sep + each_file
f = copen(each_file) #用函数copen打开防止编码错误
line_site = dict()
line_num = 0
for each_line in f:
site_num = []
line_num += 1
i = 0
while 1:
site = each_line.find(keyword, i)
if site != -1:
site_num.append(site+1) #python索引从0开始,人类习惯1开始
i = site + 1
else:
break
if site_num == []:
continue
else:
line_site = site_num
# each_txt.append(line_site) #在这里append,每找到一行就append一次,重复数据导致错误
if line_site == {}:
continue
else:
paths.append(path)
each_txt.append(line_site) #在这里append就不会有重复数据
f.close()
keyword = input('请将该脚本放于待查找的文件夹内,请输入关键字:')
search_keyword(keyword)
decide = input('请问是否需要打印关键字【%s】在文件中大的具体位置(YES/NO):' % keyword)
if decide.strip().lower()=='yes': #这样可以对付任意大小写组合,还有空格
if paths == []:
print('===================================================')
print('当前文件夹内所有文本文件均不含有此关键字!')
else:
print('===================================================')
for i in range(len(paths)): #原有的代码是有多少符合条件的文件,就把所有的答案重复打印多少次
print('在文件【%s】中找到关键字【%s】' % (paths, keyword)) #只打印和文件对应的字典
for j,k in each_txt.items():
print('关键字出现在第 %d 行,第%s个位置。' % (j, k))
# for each_path in paths: # paths有一个元素就说明有一个文件有关键字
# print('在文件【%s】中找到关键字【%s】' % (each_path, keyword))
#
# for each_line_site in each_txt: # each_txt是一个列表(每个文件一个列表),每个元素each_line_site都为字典
#
# for each_item in each_line_site.items(): # each_item是字典的每一项,是一个元组(键(行),值(列))
# print('关键字出现在第 %d 行,第' % each_item, each_item, '个位置。')# 值(列)是一个列表
txxcat 发表于 2020-4-24 01:56
你的代码还有几处错误,看注释:
天哪太感谢了!!好细心!! txxcat 发表于 2020-4-24 01:56
你的代码还有几处错误,看注释:
大神 还有一个问题,就是,如果按照我原来的代码,append会导致数据重复,我的想法重复的结果应该是:
比如在第一行的第1个字符找到关键字
那么append一个字典[{1:1}]
然后在第二行的第2个字符找到关键字
此时字典更新为{1:1, 2:2},再次append这个字典,那此时的列表each_txt应为 [{1:1}, {1:1, 2:2}]
可是为什么程序显示的是[{1:1, 2:2}, {1:1, 2:2}]
txxcat 发表于 2020-4-24 01:56
你的代码还有几处错误,看注释:
还有一个问题。。我看了标准答案,用了sort()对字典进行排序,但是为什么我的程序没有进行排序也是自动按顺序打印的?我试了好几个关键字好多次都是按照行数顺序打印的 yangxuebabe 发表于 2020-4-24 11:51
大神 还有一个问题,就是,如果按照我原来的代码,append会导致数据重复,我的想法重复的结果应该是:
...
因为append的是字典变量名而不是字典的值,做个实验:
>>> a={}
>>> a['1']=1
>>> b=[]
>>> b.append(a)
>>> b
[{'1': 1}]
>>> a['2']=2
>>> a
{'1': 1, '2': 2}
>>> b.append(a)
>>> b
[{'1': 1, '2': 2}, {'1': 1, '2': 2}]
能看明白吧?不是字典如此,列表加入列表也是如此。
为什么用sorted,个人感觉没必要,因为正常情况下字典就是按行号顺序生成的。 txxcat 发表于 2020-4-24 19:09
因为append的是字典变量名而不是字典的值,做个实验:
能看明白吧?不是字典如此,列表加入列表也是如 ...
不好意思还是没太明白,为啥字典a 变了之后再append,已经加进去的那个a也跟着变了,第一个a加进去了就是加进去了,加的就是当时的a,a改变是之后的事情啊,程序不是顺着读的吗?难道后面a的更改能影响第一个append的a?
关于sorted,我想是因为字典无序,每次加入元素是不是可能会打乱顺序?这样打印出来就不是按照行号的了。或者打印的时候可能会无序?
页:
[1]