是否有Pythonic Oneliner可以迭代文件的行



我读取文件时的时间90%,最终是这样的:

with open('file.txt') as f:
    for line in f:
        my_function(line)

这似乎是一个非常普遍的情况,所以我想到了一种较短的方式,但是这是安全的吗?我的意思是,文件会正确关闭,还是您看到此方法的其他问题?:

for line in open('file.txt'):
    my_function(line)

编辑:感谢Eric,这似乎是最好的解决方案。希望我不会将其转变为讨论,但是当我们想在多个操作中使用行时,您如何看待这种方法(不仅是作为my_function的论点):

def line_generator(filename):
    with open(filename) as f:
        for line in f:
            yield line

然后使用:

for line in line_generator('groceries.txt'):
    print line
    grocery_list += [line]

此功能是否在iTerate_over_file上有缺点?

如果经常需要,您总是可以定义:

def iterate_over_file(filename, func):
    with open(filename) as f:
        for line in f:
            func(line)

def my_function(line):
    print line,

您的Pythonic One-Liner现在是:

iterate_over_file('file.txt', my_function)

使用上下文管理器是最好的方法,这几乎可以阻止您的单线解决方案。如果您天真地想创建一个单线,您会得到:

with open('file.txt') as f:  for line in f:   my_function(line)   # wrong code!!

这是无效的语法。

所以,如果您想要一个单线,您可以做

with open('file.txt') as f:  [my_function(line) for line in f]

,但这是不好的做法,因为您仅对副作用创建列表理解(您不在乎my_function的返回)。

另一种方法是

with open('file.txt') as f:  collections.deque((my_function(line) for line in f), maxlen=0)

因此,没有创建列表的理解,您可以使用Itertools食谱强制迭代器的消耗(0大小的Deque:也没有分配的内存)

结论

要达到" Pythonic/One-Liner"目标,我们牺牲了可读性。

有时最好的方法不在一行,时期。

在ERIC的方法上构建该方法,您还可以通过编写一个将with用于open的函数来使其更加通用,然后只需返回文件即可。但是,这是:

def with_open(filename):
    with open(filename) as f:
        return f  # won't work!

不起作用,因为当功能返回时,文件f已经被with关闭。相反,您可以使其成为生成器函数,并且yield单个行:

def with_open(filename):
    with open(filename) as f:
        for line in f:
            yield line

或更短的,带有较新版本的Python:

def with_open(filename):
    with open(filename) as f:
        yield from f

并这样使用:

for line in with_open("test.txt"):
    print line

或以下:

nums = [int(n) for n in with_open("test.txt")]    

最新更新