我尝试编写一个函数,该函数接受一个字符串,并返回英语中不包含该字符串中任何字符的单词数。
op= open('words.txt')
def avoids(forbidden):
"""counts the number of words in Enlgish which do not contain any
character found in forbidden str"""
number=0
for line in op:
count=0
for letter in line.strip():
if forbidden.count(letter)==0:
count=count+1
if count==len(line.strip()):
number=number+1
return number
print(avoids('e'))
print(avoids('a'))
运行程序时,print(avoids('e'))
运行正常,打印37641;但是,print(avoids('a'))
会显示0。无论我在函数调用中作为参数放入什么字符串,第一个函数始终返回正确的值,而第二个函数始终返回0。
我是编码的新手,所以我不知道为什么会这样以及如何解决。请帮助。
答案 0 :(得分:3)
这是因为for line in op:
循环结束后,文件已读到末尾,不再需要读取任何内容。
有几种选择:
选项1(更糟)::重新打开文件:
with open('words.txt') as op:
print(avoids('e'))
with open('words.txt') as op:
print(avoids('a'))
选项2(更好)::读取所有行并将其传递给avoids()
:
def avoids(forbidden, lines):
"""counts the number of words in Enlgish which do not contain any
character found in forbidden str"""
number=0
for line in lines:
count=0
for letter in line.strip():
if forbidden.count(letter)==0:
count=count+1
if count==len(line.strip()):
number=number+1
return number
with open('words.txt') as op:
lines = op.readlines()
print(avoids('e', lines))
print(avoids('a', lines))
但是,这要求将所有行都保留在内存中,这对于较小的文件是可以的,但是对于非常大的文件可能是个问题。
选项3a (对于大文件来说更好):
这与选项1相同,但是在函数内部放置了open()
。
def avoids(forbidden, filename):
"""counts the number of words in Enlgish which do not contain any
character found in forbidden str"""
number=0
with open(filename) as op:
for line in op:
count=0
for letter in line.strip():
if forbidden.count(letter)==0:
count=count+1
if count==len(line.strip()):
number=number+1
return number
print(avoids('e', 'words.txt'))
print(avoids('a', 'words.txt'))
选项3b (也适用于非常大的文件,但我不喜欢它):
在op.seek(0)
之前添加return number
。或者,(可能更好),如@kindall在注释中提到的,可以将op.seek(0)
放在函数的开头,以确保我们在开始读取行之前位于文件的开头。这会将文件“倒带”到开头,并且只允许在函数外部打开一次文件。从本质上讲,这将使您的旧功能按预期工作。