Python-检查打开的文件
我有一个如下所示的文本文件:Python-检查打开的文件,python,python-3.x,Python,Python 3.x,我有一个如下所示的文本文件: BALLOTS CAST Riding 0 YES YES NO YES NO NO NO NO . . . YES NO YES YES Riding 1 YES NO NO YES NO NO YES NO . . . YES YES YES YES 等等。我有一个名为riding的骑乘号码的用户输入,然后我需要列出该骑乘的投票列表。例如,如果骑行选项为0,则我需要一个列表[[YES-NO-YES],[NO-NO-NO],…,[YES-NO-YES]]
BALLOTS CAST
Riding 0
YES YES NO YES
NO NO NO NO
.
.
.
YES NO YES YES
Riding 1
YES NO NO YES
NO NO YES NO
.
.
.
YES YES YES YES
等等。我有一个名为riding
的骑乘号码的用户输入,然后我需要列出该骑乘的投票列表。例如,如果骑行选项为0,则我需要一个列表[[YES-NO-YES],[NO-NO-NO],…,[YES-NO-YES]]
我需要找到一种使用readline()
和while
循环的方法。以下是我的大致情况:
ballots = open(FILENAME, 'r')
line = ballots.readline().rstrip()
L = []
i = 0
if riding.isdigit():
while i < ???:
line = ballots.readline().rstrip()
i += 1
if line == 'Riding ' + riding:
while line != '\n':
L.append(line.rstrip().split())
唯一的问题是我不知道如何使用
while
循环而不是for
循环…您需要使用状态变量来检测何时应该读取行,以及何时完成中断循环:
lines = []
with open(FILENAME, 'r') as ballots:
foundriding = False
ballots.next() # skip first line
for line in ballots:
if line.rstrip() == 'Riding ' + riding:
foundriding = True
continue
if not foundriding:
continue
line = line.rstrip()
if line and not line.startswith('Riding '):
lines.append(line)
else:
break
上述代码将跳过所有行,直到找到正确的Riding
行,此时将foundriding
设置为True。设置标志后,它会将所有后续行添加到行
,直到找到一个空行或另一个以开头的行
。在这一点上,它将打破阅读循环
另一种选择是使用:
takewhile
将从选票中提取行,直到测试返回False。之后,我们可以通过不同的测试获取更多的行,即该行不是空的,并且不是以骑行开始的
两种解决方案都不需要读取整个文件。当我们找到正确的骑术并且所有的投票都被读入行时,我们停止阅读
我像迭代器一样使用ballots
file对象。这与.readline()
的方法不同;如果.readline()
是一项硬性要求(哦,老师和家庭作业),您也可以将ballot.readline()
转换为迭代器:
ballotiterator = iter(ballots.readline, '')
然后使用ballotiterator
而不是ballots
,无论您在哪里看到用于选票中的行
,ballots.next()
或takewhile(…,ballots)
,您需要使用状态变量来检测何时应该读取行,以及何时完成中断循环:
lines = []
with open(FILENAME, 'r') as ballots:
foundriding = False
ballots.next() # skip first line
for line in ballots:
if line.rstrip() == 'Riding ' + riding:
foundriding = True
continue
if not foundriding:
continue
line = line.rstrip()
if line and not line.startswith('Riding '):
lines.append(line)
else:
break
上述代码将跳过所有行,直到找到正确的Riding
行,此时将foundriding
设置为True。设置标志后,它会将所有后续行添加到行
,直到找到一个空行或另一个以开头的行
。在这一点上,它将打破阅读循环
另一种选择是使用:
takewhile
将从选票中提取行,直到测试返回False。之后,我们可以通过不同的测试获取更多的行,即该行不是空的,并且不是以骑行开始的
两种解决方案都不需要读取整个文件。当我们找到正确的骑术并且所有的投票都被读入行时,我们停止阅读
我像迭代器一样使用ballots
file对象。这与.readline()
的方法不同;如果.readline()
是一项硬性要求(哦,老师和家庭作业),您也可以将ballot.readline()
转换为迭代器:
ballotiterator = iter(ballots.readline, '')
然后使用ballotiterator
而不是ballots
,无论您在哪里看到用于选票中的行
,ballots.next()
或takewhile(…,ballots)
另一种使用正则表达式的解决方案:
import re
with open("test.txt") as infile:
text = infile.read()
if riding.isdigit():
section = re.search(r"(?sm)^Riding " + riding + r".*?(?=Riding|\Z)", text)
matches = re.findall(r"(?:(?:YES|NO) ?)+", section.group(0))
result = [s.split() for s in matches]
print(result)
如果将骑行设置为“1”
,则会导致
[['YES', 'NO', 'NO', 'YES'], ['NO', 'NO', 'YES', 'NO'], ['YES', 'YES', 'YES', 'YES']]
当然,您可能想使用
result = [[True if value == "YES" else False for value in s.split()]
for s in matches]
相反,为了
[[True, False, False, True], [False, False, True, False], [True, True, True, True]]
没有进行错误检查(例如,输入文件中是否存在标记为的段x
),但可以简单地添加该段。使用正则表达式的另一种解决方案:
import re
with open("test.txt") as infile:
text = infile.read()
if riding.isdigit():
section = re.search(r"(?sm)^Riding " + riding + r".*?(?=Riding|\Z)", text)
matches = re.findall(r"(?:(?:YES|NO) ?)+", section.group(0))
result = [s.split() for s in matches]
print(result)
如果将骑行设置为“1”
,则会导致
[['YES', 'NO', 'NO', 'YES'], ['NO', 'NO', 'YES', 'NO'], ['YES', 'YES', 'YES', 'YES']]
当然,您可能想使用
result = [[True if value == "YES" else False for value in s.split()]
for s in matches]
相反,为了
[[True, False, False, True], [False, False, True, False], [True, True, True, True]]
没有进行错误检查(例如,输入文件中是否存在标记为的段x
),但可以简单地进行添加。查看Pickle:
它对于保存python对象并将其恢复到文件(例如列表)非常有用。看看Pickle:
它对于保存python对象并将其恢复到文件(例如列表)非常有用。您是否尝试过使用csv
模块?您是否尝试过使用csv
模块?OP希望使用while循环并理解它。您提供的解决方案很好,但似乎不相关。OP希望使用while循环并理解它。您提供的解决方案很好,但似乎不相关。建议不错,但OP只是询问循环到while循环的转换。建议不错,但OP只是询问循环到while循环的转换。