删除读取大文件的惰性方法添加的空白输出

2024-05-19 03:38:11 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用Lazy方法读取大文件,以便从文本文件中提取信息并将其存储在数据库中。你知道吗

def read_in_chunks(file_object, chunk_size=1024):
"""Lazy function (generator) to read a file piece by piece.
Default chunk size: 1k."""
while True:
    data = file_object.read(chunk_size)
    if not data:
        break
    yield data


f = open('really_big_file.dat')
for piece in read_in_chunks(f):
    process_data(piece) 

问题是,如果我将流程数据(工件)修改为例如:

for data in piece:
    data = regex.findall(str(data)) 
    cursor.execute('INSERT INTO table (Title) VALUES (?)', data)

每次读取新块时,我都会得到一个空格。在这种情况下,将其修改为:

   for data in piece:
        data = regex.findall(str(data)) 
        if (data != ""):
             cursor.execute('INSERT INTO table (Title) VALUES (?)', data[1])

但是在我提取的信息中有一些有效的“空格”(当某些字段中没有确定的信息时)。我怎样才能避免块之间的空白???我知道这不是我提取信息的方式的问题,因为如果我不使用lazy方法提取较小的文件,我就不会有这个问题。但是我有一些更大的文件,如果没有lazy方法,它的运行速度非常慢。你知道吗

谢谢


Tags: 文件方法in信息forreaddatasize
2条回答

为了补充@Gerrat的答案,这里有一个例子说明chunk_size如何破坏正则表达式搜索:

>>> from cStringIO import StringIO
>>> import re
>>> def chunker(f, chunk_size=10):
...     while True:
...         data = f.read(chunk_size)
...         if not data:
...             break
...         yield data
>>> pattern = re.compile(r"[a-zA-Z]{3}\d{3}")
>>> text = "Abc123 def456         ghi789"
>>> # on the full dataset, it's fine
... pattern.findall(text)
['Abc123', 'def456', 'ghi789']
>>> # but on chunks ...
... for data in chunker(StringIO(text)):
...     print "data: %r" % data
...     print "matches: %r" % pattern.findall(data)
data: 'Abc123 def'
matches: ['Abc123']
data: '456    '
matches: []
data: '     ghi'
matches: []
data: '789'
matches: []

如建议的那样,向chunker或处理器添加一些智能将允许您以增量方式处理事情,但要确保没有数据记录被不适当地分割。你知道吗

你的情况有几个问题。如果使用findall,那么数据可以是字符串列表。不会像那样很好地插入数据库。你知道吗

另一个问题是正则表达式可能会在您正在阅读的块之间被分解。您需要查找模式,然后在下一次搜索开始时使用任何剩余文本。你知道吗

尝试以下操作:

left_over = ''
for piece in read_in_chunks(f):
    left_over += piece
    next_start = 0
    for m in regex.finditer(left_over):
        data = m.group(0)
        next_start = m.end() + 1
        cursor.execute('INSERT INTO table (Title) VALUES (?)', data)
    left_over = left_over[next_start:]

相关问题 更多 >

    热门问题