在python中跳过某些行从文件读取并写入文件

2024-05-12 18:22:58 发布

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

我正在处理的一个更大的代码问题的一小部分:我正在从文件中读取内容:glm文件.glm。我试着写下glm文件.glm另一个文件:组合.glm跳过符合特定条件的行。你知道吗

glmfile=open("glmfile.glm",'r').readlines()
combined=open("combined.glm",'w')

的内容glm文件.glm如下所示:

...
#other objects
object node {
    name SPU123-389-3066753-3_breaker_rec_recnode;
    phases ABC;
    nominal_voltage 7621.024;
}

object node {
    name SPU123-416-25308_recnode;
    phases ABC;
    nominal_voltage 7621.024;
}
object node {
    name SPU123-403-492320;
    groupid from_db;
    phases CN;
    nominal_voltage 7621.024;
}

object node {
    name SPU123-392-97334;
    groupid from_db;
    phases ABCN;
    nominal_voltage 7621.024;
}

object node {
    name SPU123-391-348982;
    groupid from_db;
    phases AN;
    nominal_voltage 7621.024;
}

object node {
    name SPU123-391-542649;
    groupid from_db;
    phases AN;
    nominal_voltage 7621.024;
}
#few more node objects and other objects
...

现在,我形成了一个node_names数组,如下所示:

node_names=['389-3066753','403-492320','392-97334','391-348982']

我将glmfile的名称与数组中的元素进行比较,以查看对象节点名称是否列在数组node_names中:

for h,aaline in enumerate(glmfile):
    if aaline.startswith('object node {') and ('SWING' not in glmfile[h+3]):
        if glmfile[h+1][13:-2].strip() in node_names:
            #DO NOT WRITE THAT ENTIRE OBJECT NODE SECTION to 'combined'
            #I am able to skip just that line 'glmfile[h]' but how to NOT   
            #write out the entire object node i.e., glmfile[h:h+6]?
            print glmfile[h:h+6]
        else:
            combined.writelines([glmfile[h:h+6]]) 

注意:我正在努力解决的问题在if case注释中的上述代码片段中。你知道吗


Tags: 文件namefromnodedbobjectnamesglm
2条回答

让我们先谈一谈宽泛的术语,然后再具体说明。你知道吗

您的对象看起来像:

object node {
    name NAME_VAL;
    phases PHASES_VAL;
    nominal_voltage VOLTAGE_VAL;
}

您正试图从一个文件中写入这些对象到另一个空白文件中,只获取

'SWING' in PHASES_VAL and NAME_VAL in [some list of nodes].

那么,让我们这样做:

import itertools

def grouper(iterable, n, fillvalue=None)
    '''from https://docs.python.org/3/library/itertools.html'''
    args = [iter(iterable)] * n
    return itertools.zip_longest(*args, fillvalue=fillvalue)

with open('path/to/infile.txt') as inf, \
        open('path/to/outfile.txt', 'w') as outf:
    objects_in = grouper(inf, 6) # 5 lines of the object plus a newline
    for obj in objects_in:
        obj = list(obj) # let's look at them all at once
        NAME_VAL = obj[1].strip().split()[1]
        PHASES_VAL = obj[2].strip().split()[1]
        VOLTAGE_VAL = obj[3].strip().split()[1]
        if 'SWING' in PHASES_VAL and \
                NAME_VAL in some_list_of_nodes:
            outf.writelines(obj)

也就是说,如果这是您要反复做的事情,那么最好为此编写一个解析器。你知道吗

# node.py

class Node(dict):
    '''simply inheriting from dict will handle almost everything,
    but we will have to give it a classmethod to build from string'''

    @classmethod
    def from_string(cls, s):
        kwargs = {}
        reading = False
        for line in s.splitlines():
            if "}" in line:
                return cls.__init__(**kwargs)
            if reading:
                key,val = line.strip().split()
                kwargs[key]=val
            if "{" in line:
                reading = True

    def __str__(self):
        return "object node {\n" + \
                "\n".join("    {} {}".format(item)\
                          for item in self.items()) + "\n}"

你知道吗

# parser.py

from node import Node

def parse(f):
    tokens = []
    token = []
    parsing = False
    for line in inf:
        if line.startswith('object node {'):
            parsing = True
        if parsing:
            token.append(line.strip())
        if line.strip() == "}":
            parsing = False
            obj = Node("\n".join(token))
            tokens.append[obj]
            token = []
    return tokens

你知道吗

# yourfile.py

import parser

with open('path/to/infile.txt') as infile, \
        open('path/to/outfile.txt', 'w') as outfile:
    for obj in parser.parse(infile):
        if obj['name'] in some_node_names_list and \
               'SWING' in obj['phases']:
            outfile.write(str(obj))

使用额外的索引和模运算符如何:

a%b

例如:

idx = 6
for h,aaline in enumerate(glmfile):
if aaline.startswith('object node {') and ('SWING' not in glmfile[h+3]):
    if glmfile[h+1][13:-2].strip() in node_names or idx%6!=0:
        idx = idx+1
        print glmfile[h:h+6]
        pass
    else:
        combined.writelines([glmfile[h:h+6]]) 

相关问题 更多 >