仅处理非空白行

kob*_*las 6 python

我有以下代码片段

def send(self, queue, fd):
    for line in fd:
        data = line.strip()
        if data:
            queue.write(json.loads(data))
Run Code Online (Sandbox Code Playgroud)

这当然可以正常工作,但我有时会想知道是否有一种"更好"的方式来编写那种只用非空行的构造.

挑战在于它应该使用'fd'读取的迭代特性,并能够处理100+ MB范围内的文件.

更新 - 你急于得到这个问题的分数,你忽略了一个导入部分,即内存使用.例如表达式:

 non_blank_lines = (line.strip() for line in fd if line.strip())
Run Code Online (Sandbox Code Playgroud)

是要将整个文件缓冲到内存中,更不用说执行两次strip()操作了.哪个适用于小文件,但是当你有100 + MB的数据(或偶尔100GB)时会失败.

部分挑战是以下工作,但是要阅读:

for line in ifilter(lambda l: l, imap(lambda l: l.strip(), fd)):
    queue.write(json.loads(line))
Run Code Online (Sandbox Code Playgroud)

寻找魔术师!

最终更新:PEP-289对于我自己更好地理解[]和()与所涉及的迭代器之间的区别非常有用.

cmh*_*cmh 4

编写的代码没有任何问题,可读且高效。

另一种方法是将其编写为生成器理解:

def send(self, queue, fd):
    non_blank_lines = (line.strip() for line in fd if line.strip())
    for line in non_blank_lines:
        queue.write(json.loads(data))
Run Code Online (Sandbox Code Playgroud)

如果您正在应用可以采用迭代器的函数,则此方法可能会很有用(简洁):例如 python3 print

non_blank_lines = (line.strip() for line in fd if line.strip())
print(*non_blank_lines, file='foo')
Run Code Online (Sandbox Code Playgroud)

要消除对 strip() 的多次调用,请将生成器理解链接在一起

stripped_lines = (line.strip() for line in fd)
non_blank_lines = (line for line in stripped_lines if line)
Run Code Online (Sandbox Code Playgroud)

请注意,生成器表达式不会对内存产生不利影响,如本pep中详述。

要更深入地了解这种方法和一些性能基准,请查看这组注释

最后请注意,如果您不需要 strip() 的完整行为,则 rstrip() 将优于 strip()。