其他选项而不是使用 try-except

Other options instead of using try-except

当文本文件中的第 2 行有 'nope' 时,它将忽略该行并继续下一行。有没有不使用 try 和 except 的另一种写法?我可以使用 if else 语句来执行此操作吗?

文本文件示例:

0 1 
0 2 nope
1 3 
2 5 nope

代码:

e = open('e.txt')
alist = []
for line in e:
    start = int(line.split()[0])
    target = int(line.split()[1])
    try:
        if line.split()[2] == 'nope':
            continue
    except IndexError:
        alist.append([start, target])

是的,您可以使用str.endswith()方法检查行尾。

with  open('e.txt') as f:
    for line in f:
        if not line.endswith(('nope', 'nope\n')):
            start, target = line.split()
            alist.append([int(start), int(target)])

请注意,当您使用 with 语句打开文件时,您不需要显式关闭文件,文件将在块结束时自动关闭。

解决此问题的另一种更优化的方法是使用列表理解,以拒绝在每次迭代时附加到列表,并从其与常规循环相比的性能中受益。

with open('e.txt') as f:
    alist = [tuple(int(n) for i in line.split()) for line in f if not line.endswith(('nope', 'nope\n'))]

请注意,由于将字符串转换为整数和拆分行等,您的代码容易出现异常。最好使用 try-except 以防止您的代码出现可能的异常并正确处理它们。

with  open('e.txt') as f:
    for line in f:
        if not line.endswith(('nope', 'nope\n')):
            try:
                start, target = line.split()
            except ValueError:
                # the line.split() returns more or less than two items
                pass # or do smth else
            try:
                alist.append([int(start), int(target)])
            except ValueError:
                # invalid literal for int() with base 10
                pass # or do smth else

另一种 Pythonic 方法是使用 csv 模块来读取文件。在这种情况下,您不需要拆分行 and/or 使用 str.endswith().

import csv
with open("e.txt") as f:
    reader = csv.reader(f, delimiter=' ')
    alist = [(int(i), int(j)) for i, j, *rest in reader if not rest[0]]
    # rest[0] can be either an empty string or the word 'nope' if it's
    # an empty string we want the numbers. 
with open('e.txt', 'r') as f:
    alist = []
    for line in f:
        words = line.split()
        if len(words) > 2 and words[2] == 'nope':
            continue
        else:
            alist.append([int(words[0]), int(words[1])])
alist = []
with open('e.txt') as fin:
    for line in fin:
        rest_line, nope = line.strip().rsplit(' ', 1)
        if nope != 'nope':
            alist.append([int(rest_line), int(nope)])

Can I use if else statement to do this?

你应该使用 if-else 语句,而不是异常,来控制你所期望的普通“事件”的流程。这是许多语言中常见的“规则”,我认为Python不会在这里引发异常,Python 这里是个例外,但希望不会出现这种情况。

遵循您的代码但不每次都调用 line.split(),删除 try-except 并在 if:

中使用适当的条件
alist = []
with open('e.txt') as e:
    for line in e:
        splitted = line.split()
        if len(splitted) > 2 and splitted[2] == 'nope':
            continue
        else:
            alist.append([int(splitted[0]), int(splitted[1])])

当然你可以否定条件并避免 continue:

if len(splitted) <= 2 or splitted[2] != 'nope':
    alist.append([int(splitted[0]), int(splitted[1])])

当你的元素少于 2 个时,这显示了(另一个)弱点。在这里你可以使用try:这种情况下的异常告诉你输入格式错误(因为你预计至少有 2 个元素,看起来),所以你必须拒绝输入并且警告用户。此外,如果这 2 个元素不是整数,您可以拦截 ValueError

此外,如果您的输入允许包含额外的空格,您可以使用 splitted[2].strip().


关于 SO/SE 关于 try-except 问题的阅读。

  • Using try vs if in python,因此我喜欢引用:“使用 try/except 进行流量控制是完全可以的(和 "pythonic"),但是当 Exceptions 实际上很特别。”
  • Is it a good practice to use try-except-else in Python?
  • Cost of exception handlers in Python
  • Are exceptions for flow control best practice in Python?
  • Python using exceptions for control flow considered bad?

如果nope不仅可以在行尾可以用这个

with open('e.txt') as e:
    alist = [line.split() for line in e if 'nope' not in line]

print(alist)