Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 解析换行分隔文件_Python_Fileparsing - Fatal编程技术网

Python 解析换行分隔文件

Python 解析换行分隔文件,python,fileparsing,Python,Fileparsing,我正在做一个项目,我想用Python解析一个文本文件。该文件由一些数据项组成,数据块的格式各不相同。当有新行时,会找到一个新条目。这就是我想要实现的目标: 跳过前几行(前16行) 在第16行之后,有一个换行符开始新的数据输入 阅读以下几行,直到出现新的换行符。每一行都附加到一个名为data的列表中 该列表将传递给处理进一步处理的函数 重复步骤3和4,直到文件中没有更多数据 以下是该文件的一个示例: 标题信息 更多标题信息 第1行 第2行 第3行 第4行 第5行 第6行 第7行 第8行 第9行 第

我正在做一个项目,我想用Python解析一个文本文件。该文件由一些数据项组成,数据块的格式各不相同。当有新行时,会找到一个新条目。这就是我想要实现的目标:

  • 跳过前几行(前16行)
  • 在第16行之后,有一个换行符开始新的数据输入
  • 阅读以下几行,直到出现新的换行符。每一行都附加到一个名为data的列表中
  • 该列表将传递给处理进一步处理的函数
  • 重复步骤3和4,直到文件中没有更多数据
  • 以下是该文件的一个示例:

    标题信息
    更多标题信息
    第1行
    第2行
    第3行
    第4行
    第5行
    第6行
    第7行
    第8行
    第9行
    第10行
    第11行
    第12行
    第13行
    更多信息更多信息更多信息更多信息更多信息
    MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2
    更多信息3更多信息3更多信息3更多信息3更多信息3更多信息3
    更多信息4更多信息4
    字段名1 0001 0001
    字段名1 0002 0002
    字段名1 0003 0003
    字段名1 0004 0004
    字段名1 0005 0005
    字段名2 0001 0001
    字段名3 0001 0001
    字段名4 0001 0001
    字段名5 0001 0001
    字段名6 0001 0001
    更多信息更多信息更多信息更多信息更多信息
    MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2
    更多信息3更多信息3更多信息3更多信息3更多信息3更多信息3
    更多信息4更多信息4
    字段名1 0001 0001
    字段名1 0002 0002
    字段名1 0003 0003
    字段名1 0004 0004
    字段名1 0005 0005
    字段名2 0001 0001
    字段名3 0001 0001
    字段名4 0001 0001
    字段名5 0001 0001
    字段名6 0001 0001
    
    下面是我编写的一些代码。它能够读取第一个块并将其附加到列表中:

    with open(loc, 'r') as f:
        for i in range(16):
            f.readline()
    
        data = []
        line = f.readline()
        if line == "\n":
            dataLine = f.readline()
            while dataLine != "\n":
                data.append(dataLine)
                dataLine = f.readline()
    
        #pass data list to function
        function_call(data)
        # reset data list here?
        data = []
    
    如何使其适用于完整文件?我的假设是,使用“with open”,它充当“while not end of file”。在跳过前16行之后,我尝试添加一个“while True”。 我对Python的解析功能知之甚少


    感谢您在advanced中提供的任何帮助。

    在初始跳过后添加
    而为True
    ,肯定会起作用。当然,你必须弄清楚所有的细节

    您可以尝试扩展已有的方法,在外部循环中嵌套
    while
    循环。但将其视为单个循环可能更容易。对于每一行,您可能只需要做三件事:

    • 如果没有行,因为您处于EOF,
      中断
      循环,确保处理旧的
      数据
      (文件中的最后一个块),如果先有一个
    • 如果是空行,则启动新的
      数据
      ,确保先处理旧的
      数据
    • 否则,请附加到现有的
      数据
    因此:

    有几种方法可以进一步简化此过程:

    • 对f:中的行使用
      ,而不是重复执行
      f.readline()
      并检查的
      循环
    • 用于将行迭代器转换为空行分隔行组迭代器

    如果您仍在努力解决这个问题,这里有一个实现,它使用和一个键函数
    search()
    读取示例数据:


    这将导致数据结构是块的嵌套列表。每个子列表由数据文件中的
    \n
    分组分开。

    文件中的块模式是它们由以空行或文件结尾的行组组成。这个逻辑可以封装在一个生成器函数中,该函数从文件中迭代生成行块,从而简化脚本的其余部分

    在下面的代码中,
    getlines()
    是生成器函数。还请注意,将跳过文件的前17行,以到达第一个块的开头

    from pprint import pformat
    
    loc = 'parsing_test_file.txt'
    
    def function(lines):
        print('function called with:\n{}'.format(pformat(lines)))
    
    def getlines(f):
        lines = []
        while True:
            try:
                line = next(f)
                if line != '\n':  # not end of the block?
                    lines.append(line)
                else:
                    yield lines
                    lines = []
            except StopIteration:  # end of file
                if lines:
                    yield lines
                break
    
    with open(loc, 'r') as f:
        for i in range(17):
            next(f)
    
        for lines in getlines(f):
            function(lines)
    
    print('done')
    
    使用测试文件输出:

    函数调用时使用:
    ['MoreInfo MoreInfo MoreInfo\n',
    'MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2\n',
    'MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3\n',
    “MoreInfo4 MoreInfo4\n”,
    “FieldName1 0001 0001\n”,
    “FieldName1 0002 0002\n”,
    “FieldName1 0003 0003\n”,
    “FieldName1 0004 0004\n”,
    “FieldName1 0005 0005\n”,
    “FieldName2 0001 0001\n”,
    “FieldName3 0001 0001\n”,
    “FieldName4 0001 0001\n”,
    “FieldName5 0001 0001\n”,
    '字段名6 0001 0001\n']
    使用以下命令调用函数:
    ['MoreInfo MoreInfo MoreInfo\n',
    'MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2 MoreInfo2\n',
    'MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3 MoreInfo3\n',
    “MoreInfo4 MoreInfo4\n”,
    “FieldName1 0001 0001\n”,
    “FieldName1 0002 0002\n”,
    “FieldName1 0003 0003\n”,
    “FieldName1 0004 0004\n”,
    “FieldName1 0005 0005\n”,
    “FieldName2 0001 0001\n”,
    “FieldName3 0001 0001\n”,
    “FieldName4 0001 0001\n”,
    “FieldName5 0001 0001\n”,
    '字段名6 0001 0001\n']
    完成
    
    First:“我的假设是使用“with open”,它充当“while not end of file”(而不是文件的结尾)。”这是错误的<代码>打开时
    不执行任何循环;它只是确保你打开的文件在你完成后会被关闭。更重要的是:“我尝试在跳过前16行后添加一个while True”是一个非常好的方法。如果它对你不起作用,显然你出了问题。如果您向我们展示您尝试的代码,我们可以向您展示如何修复它;如果你只是描述一下,没有人能为你做什么。你应该研究一下如何使用
    itertools.groupby()
    ,并创建一个键函数,当它自己看到一个
    \n
    时会发生变化。例如:你需要“重复”代码块
    from itertools import groupby, repeat
    
    def search(d):
        """Key function used to group our dataset"""
    
        return d[0] == "\n"
    
    def read_data(filename):
        """Read data from filename and return a nicer data structure"""
    
        data = []
    
        with open(filename, "r") as f:
            # Skip first 16 lines
            for _ in repeat(None, 16):
                f.readline()
    
            # iterate through each data block
            for newblock, records in groupby(f, search):
                if newblock:
                    # we've found a new block
                    # create a new row of data
                    data.append([])
                else:
                    # we've found data for the current block
                    # add each row to the last row
                    for row in records:
                        row = row.strip().split()
                        data[-1].append(row)
    
        return data
    
    from pprint import pformat
    
    loc = 'parsing_test_file.txt'
    
    def function(lines):
        print('function called with:\n{}'.format(pformat(lines)))
    
    def getlines(f):
        lines = []
        while True:
            try:
                line = next(f)
                if line != '\n':  # not end of the block?
                    lines.append(line)
                else:
                    yield lines
                    lines = []
            except StopIteration:  # end of file
                if lines:
                    yield lines
                break
    
    with open(loc, 'r') as f:
        for i in range(17):
            next(f)
    
        for lines in getlines(f):
            function(lines)
    
    print('done')