【问题标题】:what can i do to optimize this function, and make it looks like more pythonic? [closed]我能做些什么来优化这个功能,让它看起来更像pythonic? [关闭]
【发布时间】:2013-10-22 08:10:49
【问题描述】:

我可以做些什么来优化这个功能,让它看起来更像pythonic?

def flatten_rows_to_file(filename, rows):
    f = open(filename, 'a+')
    temp_ls = list()
    for i, row in enumerate(rows):
        temp_ls.append("%(id)s\t%(price)s\t%(site_id)s\t%(rating)s\t%(shop_id)s\n" % row)
        if i and i % 100000 == 0:
            f.writelines(temp_ls)
            temp_ls = []
    f.writelines(temp_ls)
    f.close()

【问题讨论】:

  • 对于初学者,您可以使用with open(filename, 'a+') as f: 确保在出现异常时关闭文件。
  • 这个问题似乎是题外话,因为它属于 CodeReview.SE。

标签: python coding-style


【解决方案1】:

立即想到的一些事情:

  1. 使用with 语句,而不是手动关闭文件。
  2. 将生成器表达式传递给f.writelines,而不是一遍又一遍地构建一个 100000 行的列表(让标准库处理缓冲输出的多少(如果有的话))。
  3. 或者,更好的是,使用csv 模块来处理编写制表符分隔的输出。

以下是一些改进代码的快速介绍:

from csv import DictWriter

def flatten_rows_to_file(filename, rows):
    with open(filename, 'ab') as f:
        writer = DictWriter(f, ['id','price','site_id','rating','shop_id'],
                            delimiter='\t')
        writer.writerows(rows)

请注意,如果您使用的是 Python 3,则打开文件所需的代码略有不同。使用模式'a' 而不是'ab' 并添加关键字参数newline=""。在您使用的模式下,您不需要+(您只是在写,而不是同时写和读)。

如果您的 rows 参数中的值可能有超出您编写的键的额外键,则您还需要将一些额外的参数传递给 DictWriter 构造函数。

【讨论】:

  • 如果行大于1G或更多?而你的电脑内存只有1G。
  • @user2000477:rows 是某种生成器吗?如果没有,那么在代码运行之前你就已经内存不足了。如果它是一个生成器,f.writelinescsv.DictWriter.writerows 都会做正确的事情,在写入时仅将单行数据保留在内存中。他们基本上是在 tobias_k 的答案中循环(虽然在 C 代码中,所以可能更快)。
【解决方案2】:

使用with 语句来确保文件正确关闭通常是个好主意。此外,除非我弄错了,否则不需要手动缓冲这些行。您也可以在打开文件时指定缓冲区大小,确定how often the file is flushed

def flatten_rows_to_file(filename, rows, buffsize=100000):
    with open(filename, 'a+', buffsize) as f:
        for row in rows:
            f.write("%(id)s\t%(price)s\t%(site_id)s\t%(rating)s\t%(shop_id)s\n" % row)

【讨论】:

    猜你喜欢
    • 2011-02-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2013-04-19
    • 1970-01-01
    相关资源
    最近更新 更多