Python - 读取文件并通过分隔符分隔行的最佳方法

Mat*_*ock 0 python file-io generator

读取文件并通过分隔符划分行的最佳方法是什么.返回的数据应该是元组列表.

这种方法可以被打败吗?这可以更快/使用更少的内存吗?

def readfile(filepath, delim):
    with open(filepath, 'r') as f:
        return [tuple(line.split(delim)) for line in f]
Run Code Online (Sandbox Code Playgroud)

Pau*_*McG 14

您发布的代码读取整个文件,并在内存中构建该文件的副本,作为分成元组的所有文件内容的单个列表,每行一个元组.由于您询问如何使用更少的内存,您可能只需要一个生成器函数:

def readfile(filepath, delim): 
    with open(filepath, 'r') as f: 
        for line in f:
            yield tuple(line.split(delim))
Run Code Online (Sandbox Code Playgroud)

但!有一个重要的警告!您只能迭代readfile返回的元组一次.

lines_as_tuples = readfile(mydata,','):

for linedata in lines_as_tuples:
    # do something
Run Code Online (Sandbox Code Playgroud)

到目前为止,这是可以的,并且生成器和列表看起来相同.但是,假设您的文件包含大量浮点数,并且您在文件中的迭代计算了这些数字的总体平均值.您可以使用"#do something"代码来计算总数和数字,然后计算平均值.但现在让我们说你想再次迭代,这次是为了找出每个值的平均值的差异.你认为你只需添加另一个for循环:

for linedata in lines_as_tuples:
    # do another thing
    # BUT - this loop never does anything because lines_as_tuples has been consumed!
Run Code Online (Sandbox Code Playgroud)

BAM!这是生成器和列表之间的巨大差异.现在代码中的这一点,生成器已被完全消耗 - 但没有引发特殊异常,for循环什么都不做,继续,静默!

在许多情况下,您将获得的列表只迭代一次,在这种情况下,readfile到生成器的转换就可以了.但是如果你想要的是一个更持久的列表,你将多次访问,那么只使用一个生成器会给你带来问题,因为你只能迭代一次生成器.

我的建议?使readlines成为一个生成器,这样在它自己的世界观点中,它只会产生文件的每个增量位,既美观又节省内存.将保留数据的负担放在调用者身上 - 如果调用者需要多次引用返回的数据,那么调用者可以简单地从生成器构建自己的列表 - 使用Python轻松完成list(readfile('file.dat', ',')).