简体   繁体   English

Python:读取文件中的整数并将其添加到列表中

[英]Python: reading integers in a file and adding them to a list

I am trying to create a function that takes an open file as an argument, reads the integers in the file which are all on their own line, then creates a list of those integers. 我正在尝试创建一个函数,该函数将打开的文件作为参数,读取文件中所有位于其自己行上的整数,然后创建这些整数的列表。 The function should stop reading the file when there is an empty line. 空行时,该函数应停止读取文件。 This is what I am stuck on. 这就是我所坚持的。

def load_ints(file):
    lst = []
    x = 1
    while x == 1:
        for line in file:
            if len(line.strip()) != 0:
                load = line.split()
                load = [int(i) for i in load]
                lst = lst + load
            else:
                x = 2
        x = 2
    return lst

the file I am testing it with looks like this: 我正在测试的文件如下所示:

  1
  0
  -12
  53
  1078

  Should not be read by load_ints!
len(line.strip()) != 0:  

is not working, it currently gives me a ValueError: invalid literal for int() with base 10: 'Should' 无法正常工作,它目前给我一个ValueError:int()的无效文字,基数为10:“应该”

You need to put a break after the x = 2 您需要在x = 2之后稍作break

        else:
            x = 2
            break

Otherwise, the for loop will keep iterating over the file. 否则, for循环将继续遍历文件。 It has read the blank line, executed the else condition, then carried on processing lines. 它已读取空白行,执行else条件,然后继续处理行。 So it tries to process the 'Should...' line, and fails because 'Should...' is not an integer. 因此它尝试处理“应该...”行,但由于“应该...”不是整数而失败。

Also, I don't see why you have the while statement. 另外,我不明白为什么要使用while语句。 The for loop should be enough to iterate over the file and process each line, and the break I've suggested will exit the loop when you hit the blank line. for循环应足以遍历文件并处理每一行,而当空行出现时,我建议的break将退出循环。

Other answers already point out the issue: you have to stop parsing the integers when encoutering the blank line. 其他答案已经指出了这个问题:在对空行进行包围运算时,必须停止解析整数。

Here's a one-liner using itertools.takewhile , stopping when stripping the line yields an empty line & converting to integer: 这是使用itertools.takewhile的单行代码,在剥离行时停止会产​​生空行并转换为整数:

import itertools

def load_ints(file):
    return [int(x) for x in itertools.takewhile(str.strip,file)]

result: 结果:

[1, 0, -12, 53, 1078]

So itertools.takewhile iterates on the file lines, and applies strip on each line. 因此itertools.takewhilefile行上进行迭代,并在每一行上应用strip If the result is an empty string, it stops the iteration. 如果结果为空字符串,则停止迭代。 Otherwise it continues so the line is converted to integer and added to the list comprehension. 否则它将继续,因此该行将转换为整数并添加到列表推导中。

The less lines you're writing in those cases, the less bugs you'll create with auxiliary variables & states. 在这种情况下,您写的行越少,使用辅助变量和状态创建的错误就越少。

When you read a file you get a generator. 当您读取文件时,您将获得一个生成器。 Instead of reading it all to memory we could use the while loop to feed us with 1 row at a time and break when condition is met (row is blank). 与其将所有内容读取到内存中,我们不如使用while循环一次向我们喂入1行,并在满足条件时中断(行为空白)。 This should be the most efficient solution. 这应该是最有效的解决方案。

data = """\
1
2
-10
1241

Empty line above"""

with open("test.txt","w") as f:
    f.write(data)

with open("test.txt") as f:
    data = []
    while True:
        row = next(f).strip()
        try:
            data.append(int(row))
        # Break if ValueError is raised (for instance blank line or string)
        except ValueError:
            break

data

Returns: 返回值:

[1, 2, -10, 1241]

If you want a compact solution we could use takewhile from itertools. 如果您想要一个紧凑的解决方案,我们可以使用itertools中的takewhile。 But this won't handle any error. 但这不会处理任何错误。

from itertools import takewhile

with open("test.txt") as f:
    data = list(map(int,takewhile(lambda x: x.strip(), f)))

I think it is not necessary the while. 我认为这是没有必要的。

def load_ints(file):
    lst = []
    for line in file:
        if len(line.strip()) != 0:
            load = line.split()
            load = [int(i) for i in load]
            lst.append(load)
        else:
            break

    return lst

If you want to stop reading the file when the line is empty, you have to break the for loop : 如果您想在行为空时停止读取文件,则必须中断for循环:

def load_ints(file):
    lst = []
    for line in file:
        if len(line.strip()) != 0:
            load = line.split()
            load = [int(i) for i in load]
            lst = lst + load
        else:
            break
    return lst

You can also use re module: 您还可以使用re模块:

import re
def load_ints(my_file):
    return list(map(int, re.findall('-?\d', my_file.read())))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM