我正在检查文本文件中分号的位置。我有一个长度分隔的文本文件,它有数千行,看起来像这样:
AB;2;43234;343;
CD;4;41234;443;
FE53234;543;
FE;5;53;34;543;
我使用下面的代码来检查分号的正确位置。如果分号在我预期的位置丢失,则打印一条语句:
import glob
path = r'C:\path\*.txt'
for fname in glob.glob(path):
print("Checking file", fname)
with open(fname) as f:
content = f.readlines()
for count, line in enumerate(content):
if (line[2:3]!=";"
or line[4:5]!=";"
or line[10:11]!=";"
# really a lot of continuing entries like these
or line[14:15]!=";"
):
print("\nSemikolon expected, but not found!\nrow:", count+1, "\n", fname, "\n", line)
代码正常工作,没有抛出错误,并且检测到数据行。
我现在的问题是,我有很多分号要检查,我真的有很多连续的条目,如
or line[xx:xx]!=";"
我认为这是没有效率的,有两点:
1.有这么多代码行在视觉上不太好。我认为它可以缩短。
1.从逻辑上讲,有这么多的拆分or
检查是没有效率的。我认为它可能会更有效率,可能会减少运行时间。
我在寻找一种有效的解决方案,它:
1.提高可读性
1.最重要的是:减少了运行时间(因为我认为现在编写它的方式效率很低,使用了所有的or语句)
我只想检查是否有分号在我期望的地方。在我需要的地方。我不关心任何额外的分号在数据字段。
2条答案
按热度按时间p8h8hvxi1#
只是从你写的开始:
如果行的长度少于15个字符,这将引发异常,而且,像
;;;;;;;;;;;;;;;
这样的行在技术上是有效的。EDIT:假设您有一个输入文件,如下所示:
(Note:结尾的空行)我提供的解决方案工作正常。我没有看到任何异常或
Semicolon expected on line #...
输出。如果您的输入文件以两个空行结尾,这将引发异常。如果您的输入文件在中间的某个地方包含空行,这也将引发异常。如果您的文件中的行长度小于15个字符(不包括最后一行),这将引发异常。
您可以简单地说,每一行都必须满足两个条件才能被视为有效:
1.当前行的长度必须至少为15个字符(或
max(delimiter_indices) + 1
个字符)。1.当前行中分隔符索引处的所有字符都必须是分号。
代码:
编辑:我的错,我为了可读性而破坏了短路评估。下面的代码应该可以工作:
如果行的长度不正确,则表达式的后半部分将由于短路计算而不计算,这应该会阻止
IndexError
。编辑:由于您有很多文件,每行有很多分号,您可以在循环之前进行
max(delimiter_indices)
计算,以避免为每行计算该值。这可能不会产生很大的差异,但您也可以直接迭代file对象(每次迭代都产生下一行),而不是在通过lines = file.readlines()
迭代之前将整个文件加载到内存中。虽然没有使用all
或any
那么有趣,但我决定将has_correct_semicolons
表达式转换为一个实际的循环,它可以迭代分隔符索引-这样,您的错误消息可以更明确一些,指向出错行的出错索引。有一个单独的错误消息,当一行太短。x6h2sr282#
如果您只想验证行的结构,可以使用一个正则表达式,这样在需求发生变化时易于维护:
Regex demo here.
如果您实际上并不关心内容,而只想检查
;
的位置,则可以将正则表达式简化为:r".{2};.;.{5};.{3};"
Demo for the dot regex.