0

对于我的函数,我有一个给定输入文件的规则列表。如果在给定的文件中违反了其中任何一个,我希望我的程序返回错误消息并退出。

  • 第一行应以“#”符号开头(表示标题行)
  • 每行应该正好有 10 列
  • 第 2 列(从 0 开始计数)应该是 + 或 - 符号
  • 第 8 列应该是一个以逗号分隔的整数列表
  • 第 9 列应该是一个以逗号分隔的整数列表,整数个数与第 8 列完全相同。

为了尝试做到这一点,我编写了以下代码:

将史蒂夫哈的答案编辑成代码

with open(infile, 'r') as fp:
line = fp.readline().strip()
if not line.startswith('#'):
    print ('First line does not start with #')
    sys.exit(1)
n = 1
for line in fp.readlines():
    d = '(\d+,\d+)'
    n += 1
    cols = line.strip().split()
    i = search(d, line)
    if len(cols) != 10:
        print('Lenth not equal to 10')
        sys.exit(1)
    if cols[2] != '+' or '-':
        print('Column 2 is not a + or - symbol')
        sys.exit(1)
    if i and cols[8] != i.group(1):
        print('Column 8 is not a comma-separated list of integers')
        sys.exit(1)
    if i and cols[9] != i.group(1) and len(cols[9]) != len(cols[8]):
        print('Column 9 in not a comma-separated list of integers with the exact same number of integers in column 8')
        sys.exit(1)

然而,当我运行它时,并不是所有的条件似乎都是有效的。我正在尝试正确地做到这一点?

4

1 回答 1

3

这一行是错误的:

if cols[2] != '+' or '-':

这是正确的:

if not (cols[2] == '+' or cols[2] =='-'):

我建议这样做:

if cols[2] not in ('+', '-'):

另外,我建议你不要打电话fp.readlines()。文件对象fp作为一个迭代器工作,当你迭代它时,你一次得到一行。所以你的循环会变成:

for line in fp:

另外,看起来n正在跟踪行号?在这种情况下,有一种惯用的 Python 方式可以做到这一点,如下所示:

for n, line in enumerate(fp, 1):

enumerate()接受一个迭代器并从迭代器返回下一个值以及一个递增的计数。默认情况下,计数从 0 开始,但您可以选择指定一个起始数字,就像我在此处所做的那样使其从 1 开始。

在 Python 中使用with语句打开文件是最佳实践,所以我建议你这样做:

with open(infile, 'r') as fp:
    line = fp.readline().strip()
    if not line.startswith('#'):
        print ('First line does not start with #')
        sys.exit(1)
    for line in fp:
        # process lines here

您显示的代码对我来说并不完全有意义。这一行:

i = search(d, line)

您必须已经执行了from re import search命令。我实际上建议只是做import re然后明确调用re.search(),但我想这是一个偏好问题。无论如何,这将设置i为匹配组的结果re.search()(或者None如果匹配失败)。但是稍后在您正在测试的代码中,r而不是i,并且您从未r在我们在这里看到的任何代码中设置,所以我不确定那会做什么。我个人将m其用作匹配组的变量名。

您的正则表达式只匹配一对正整数。没有什么可以计算有多少整数。 len(cols[8])正在检查 中有多少个字符cols[8]

您正在调用一个字符串方法函数.split(''),这是不正确的。在我的系统上,它引发了一个例外:只需在空白处ValueError: empty separator 调用拆分;.split()我假设逗号分隔的整数列表不能有任何空格。

最后,请考虑 PEP 8 中的指南。您的变量FirstLine像类名一样大写,而不是变量名;这并没有完全让我感到困惑,但它有点让人分心。大多数 Python 社区都遵循 PEP 8。

http://www.python.org/dev/peps/pep-0008/

考虑到以上所有因素,我只是重新编写了您的代码:

import sys

def parse_list_of_int(s):
    try:
        return [int(x) for x in s.split(',')]
    except Exception:
        return None

with open("test.txt", 'r') as f:
    # read line 1
    line = f.readline().strip()
    if not line.startswith('#'):
        print ('First line does not start with #')
        sys.exit(1)

    # need to start enumerate() at 2 because we pulled line 1 out above
    for i, line in enumerate(f, 2):
        cols = line.strip().split()
        if len(cols) != 10:
            print('line {0}: Length not equal to 10'.format(i))
            sys.exit(1)
        if cols[2] not in ('+', '-'):
            print('line {0}: Column 2 is not a + or - symbol'.format(i))
            sys.exit(1)
        lst8 = parse_list_of_int(cols[8])
        if lst8 is None:
            print('line {0}: Column 8 is not a comma-separated list of integers').format(i)
            sys.exit(1)
        lst9 = parse_list_of_int(cols[9])
        if lst9 is None:
            print('line {0}: Column 9 is not a comma-separated list of integers'.format(i))
            sys.exit(1)
        if len(lst8) != len(lst9):
            print('line {0}: Column 8 and column 9 do not have same number of integers'.format(i))
            sys.exit(1)

print('No problems!')
sys.exit(0)

我编写了一个简单的函数来解析整数列表,构建一个 Python 列表并返回它。然后代码实际上可以正确检查两个列表是否相同长度。

于 2012-04-24T20:45:58.433 回答