如何逐块读取大文件并按块标题判断?

时间:2018-11-28 00:20:21

标签: python

我有一个大文件,我想通过匹配标题逐块读取。 例如,文件如下:

@header1
a b c 1 2 3
c d e 2 3 4
q w e 3 4 5


@header2
e 89 78 56
s 68 77 26
...

我写了这样的脚本:

with open("filename") as f:
  line=f.readline()
  if line.split()[0]=="@header1":
     list1.append(f.readline().split()[0])
     list2.append(f.readline().split()[1])
     ...
  elif line.split()[0]=="@header2":
     list6.append(f.readline().split()[0])
     list7.append(f.readline().split()[1])
     ...

但是它似乎只读取第一个标头,而没有读入第二个块。此外,这些块之间还有一些空行。当该行与某些字符串匹配并跳过那些空行时,如何读取该块。

我知道在C语言中会切换。如何在python中做类似的事情?

4 个答案:

答案 0 :(得分:1)

IMO,您的误解是关于如何读取csv文件。至少我怀疑从C进行“切换”是否会比使用if子句更有用。

不过,请理解,您必须逐行遍历文件 。也就是说,如果您之前不知道长度,那么没有什么可以处理整个块的。

所以您的算法就像:

对于文件中的每一行:
。是标题吗?
。 。 。然后准备该特定的标头
。 。是空行吗?
。 。 。然后跳过
。是数据吗?
。 。 。然后根据上面的准备进行添加

在代码中,这可能有点像

last

答案 1 :(得分:0)

我不知道您到底想实现什么,但是也许是这样的:

Dialer

答案 2 :(得分:0)

底部附有一个解决方案,该解决方案使用Python生成器split_into_chunks(f)提取每个部分(作为字符串列表),消除空行,检测缺少的@header和EOF。生成器方法确实很简洁,因为它允许您进一步包装例如处理空格分隔值的CSV阅读器对象(例如pandas read_csv):

with open('your.ssv') as f:
    for chunk in split_into_chunks(f):
        # Do stuff on chunk. Presumably, wrap a reader e.g. pandas read_csv
        # print(chunk)

代码在下面。我还为您参数化了值demarcator='@header'。请注意,我们必须使用line = inputstream.readline()while line进行迭代,而不是通常使用for line in f进行迭代,因为如果我们看到下一部分的@header,则需要使用{{ 1}};有关原因,请参见thisthis。而且,如果您要修改生成器以分别产生块头和主体(例如,作为两个项目的列表),那么这很简单。

seek/tell()

答案 3 :(得分:0)

我看到了另一个与此问题类似的帖子,并在此处复制了这个想法。我同意SpghttCd是正确的,尽管我没有尝试过。

    with open(filename) as f:
        #find each line number that contains header
        for i,line in enumerate(f,1):
            if 'some_header' in line:
                index1=i
            elif 'another_header' in line:
                index2=i
            ...
    with open(filename) as f:
        #read the first block:
        for i in range(int(index1)):
            line=f.readline()
        for i in range('the block size'):
            'read, split and store'
        f.seek(0)
        #read the second block, third and ... 
        ...