关于python:其他选项而不是使用try-except

Other options instead of using try-except

当文本文件中的第2行有"nope"时,它将忽略该行并继续下一行。有没有其他方法不用try和except来写这个?我可以用if else语句来做这个吗?

文本文件示例:

1
2
3
4
0 1
0 2 nope
1 3
2 5 nope

代码:

1
2
3
4
5
6
7
8
9
10
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()方法检查行的尾部。

1
2
3
4
5
6
with  open('e.txt') as f:
    for line in f:
        if not line.endswith(('nope', 'nope
'
)):
            start, target = line.split()
            alist.append([int(start), int(target)])

注意,当使用with语句打开文件时,不需要显式关闭文件,文件将在块的末尾自动关闭。

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

1
2
3
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
'
))]

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with  open('e.txt') as f:
    for line in f:
        if not line.endswith(('nope', 'nope
'
)):
            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

另一种尚未完成的方法是使用csv模块读取文件。在这种情况下,您不需要拆分行和/或使用str.endswith()

1
2
3
4
5
6
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.


1
2
3
4
5
6
7
8
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])])


如果nope不仅可以在行尾,还可以使用它

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

print(alist)

Can I use if else statement to do this?

您应该使用if-else语句(而不是异常)来控制流程,以防出现您所期望的普通"事件"。这是许多语言中常见的"规则",我认为python不会在这里引发异常,python在这里是一个异常,但希望在这种情况下不会。

遵循您的代码,但每次都不调用line.split(),删除尝试,除非在if中使用适当的条件:

1
2
3
4
5
6
7
8
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

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

它显示了(另一个)弱点,以防您的元素少于2个。这里您可以使用try:exception在本例中告诉您输入格式错误(因为您希望至少有2个元素,看起来),所以您必须拒绝输入并警告用户。另外,如果这两个元素不是整数,则可以截取ValueError

此外,如果您的输入允许包含额外的空间,那么您可以使用类似于splitted[2].strip()的内容。

关于这次尝试的其他内容。

  • 在python中使用try-vs-if,我喜欢引用其中的一句话:"使用try/除了流控制之外,完全可以(和"pythonic"),但是当Exceptions实际上是异常的时候,这是最有意义的。"
  • 在python中使用try-except-else是一个好的实践吗?
  • python中异常处理程序的成本
  • Python中的流控制最佳实践是否有例外?
  • 对于控制流使用异常的python是否被认为是坏的?


1
2
3
4
5
6
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)])