Python:如何解析文本fi并向其添加内容

2024-04-25 20:45:18 发布

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

你好,我有一个特殊格式的网络,即.gdf。但是,这是一个以下格式的文本文件

network:
nodedef>name VARCHAR,label VARCHAR
0,' 0 '
1,' 1 '
2,' 2 '
edgedef>node1 VARCHAR,node2 VARCHAR,weight DOUBLE
0,1,0.2
0,2,0.2
0,3,0.2
0,4,0.333333

其中第一部分是指节点,第二部分是指边。在

我想添加feature来读取文件并向节点添加一个特性并返回以下内容:

^{pr2}$

Tags: name网络节点格式networklabeldouble文本文件
1条回答
网友
1楼 · 发布于 2024-04-25 20:45:18

这里有一些代码可以完成您所要求的前半部分。它将解析.GDF文件,并使信息对您可用。添加属性并编写它们是留给读者的练习。在

import ast
import collections
import re


def main():
    parser = GDFParser()
    with open('network.gdf') as file:
        parser.read(file)
    print(*parser.data, sep='\n')


def pivot(iterable):
    columns = []
    for row in iterable:
        columns.extend([] for _ in range(len(row) - len(columns)))
        for column, cell in zip(columns, row):
            column.append(cell)
    return columns


class GDFParser:

    HEADER = re.compile('\w+:')
    DEF = re.compile('\w+>\w+ (?:DOUBLE|VARCHAR)(?:,\w+ (?:DOUBLE|VARCHAR))*')
    CAST = dict(DOUBLE=float, VARCHAR=str)

    def __init__(self):
        self.__header = None
        self.__type = []
        self.__data = []

    @property
    def header(self):
        return self.__header

    @property
    def data(self):
        return tuple(self.__data)

    def read(self, file):
        for line in file:
            self.__read_line(line.strip())

    def __read_line(self, line):
        if self.HEADER.fullmatch(line):
            self.__process_header(line)
        elif self.DEF.fullmatch(line):
            self.__process_def(line)
        else:
            self.__process_data(line)

    def __process_header(self, line):
        if self.header:
            raise ValueError('header was previously set')
        self.__header = line[:-1]

    def __process_def(self, line):
        name, fields = line.split('>')
        columns, casts = pivot(field.split() for field in fields.split(','))
        self.__type.append((collections.namedtuple(name, columns),
                            tuple(map(self.CAST.__getitem__, casts))))

    def __process_data(self, line):
        if not self.__type:
            raise ValueError('a definition must come before its data')
        kind, casts = self.__type[-1]
        self.__data.append(kind(*(cast(item) for cast, item in
                                  zip(casts, ast.literal_eval(line)))))


if __name__ == '__main__':
    main()

相关问题 更多 >

    热门问题