14

我经常使用逗号/制表符分隔的数据文件,这些文件可能如下所示:

key1,1,2.02,hello,4
key2,3,4.01,goodbye,6
...

我可能会在 Python 中将其读取并预处理为列表列表,如下所示:

[ [ key1, 1, 2.02, 'hello', 4 ], [ key2, 3, 4.01, 'goodbye', 6 ] ]

有时,我喜欢将此列表保存为泡菜,因为它保留了我的条目的不同类型。但是,如果腌制文件很大,那么以流式方式读取此列表列表会很棒。

在 Python 中,要将文本文件作为流加载,我使用以下命令打印出每一行:

with open( 'big_text_file.txt' ) as f:
    for line in f:
        print line

我可以为 Python 列表做类似的事情吗,即:

import pickle
with open( 'big_pickled_list.pkl' ) as p:
    for entry in pickle.load_streaming( p ): # note: pickle.load_streaming doesn't exist
        print entry

是否有像“load_streaming”这样的泡菜功能?

4

2 回答 2

18

这会奏效。

然而,它所做的是从文件中取出一个对象,然后将文件的其余内容打印到stdout

你可以做的是这样的:

import cPickle
with open( 'big_pickled_list.pkl' ) as p:
    try:
        while True:
            print cPickle.load(p)
    except EOFError:
        pass

这将取消文件中的所有对象,直到达到 EOF。


如果你想要类似 的东西for line in f:,你可以很容易地把它包装起来:

def unpickle_iter(file):
    try:
        while True:
             yield cPickle.load(file)
    except EOFError:
        raise StopIteration

现在你可以这样做:

with open('big_pickled_list.pkl') as file:
    for item in unpickle_iter(file):
        # use item ...
于 2013-07-12T20:37:28.177 回答
2

为了跟进我对已接受解决方案的评论,我建议使用更像这样的循环:

import cPickle
with open( 'big_pickled_list.pkl' ) as p:
    while p.peek(1):
        print cPickle.load(p)

这样,如果文件中有损坏的对象,您将继续收到 EOFError 异常。

为了完整性:

def unpickle_iter(file):
    while file.peek(1):
        yield cPickle.load(file)
于 2016-04-19T14:52:35.727 回答