开发者

replace names with lists from file

I have a file like divided in sections like that:

[main]

a
b
< sectionA
c

[sectionA]
x
< sectionB
y
z

[sectionB]
q
w
e

I want to replace the "< sectionA" w开发者_运维技巧ith contents from sectionA and so on. The final result should be a list with only the elements in the right order, like that: ['a', 'b', 'x', 'q', 'w', 'e', 'y', 'z', 'c']

A made the code below that fill the file in a dictionary with lists, but the order is not that I used in insertion (so I can't be sure where I start).

I also don't know the best way to replace the "< sectionA" things with the contents from the actual list...

import re
filename = input('Insert filename: ')
f = open(filename)
lines = f.readlines()

elements = {}
name = ''

for i in lines:
    if i[-1] == '\n':
        i = i[:-1]
    if not i:
        continue
    sec = re.findall(r'\[(\w+)\]', i)
    if sec != []:
        name = sec[0]
        elements[name] = []
    else:
        elements[name] += [i]

print(elements)

and the result is: {'main': ['a', 'b', '< sectionA', 'c'], 'sectionB': ['q', 'w', 'e'], 'sectionA': ['x', '< sectionB', 'y', 'z']}


I made some crazy code for you:

import collections
def load(fname):
    d = collections.OrderedDict()
    for i in (line.rstrip('\n') for line in open(fname) if line[:-1]):
        d.update({i[1:-1]:[], '_':i[1:-1]}) \
        if i.startswith('[') else d[d['_']].append(i)
    return d

def join(first, dic):
    f = dic[first]
    for i,j in ((i,j[2:]) for i,j in enumerate(f) if j.startswith('<')):
        f[i:i+1] = join(j, dic)
    return f

d = load('file.txt')
join(next(iter(d)), d)

as the join function inserts the code in the right list, it will not have to compute the lists more than once if required in two or more places. :)

Using OrderedDict, you always start with the right list.


It's not that hard. This is the algorithm:

1. Find all indexes in main starting with <.
2. If none are found, go to 5.
3. Replace every index with the according section (inserted unpacked).
4. Go to 1.
5. Done.


I solved your problem with two functions. The first for rendering the input file (renderfile(filename)) into a Python dictionary, and the second to merge the contents with the section-references with a starting section (rendercontents(contents, startsection)):

def renderfile(filename):
    contents = {}
    with open(filename) as f:
        currentsection = ""
        for line in f.readlines():
            if line == "\n":
                continue
            line = line.replace("\n", "")
            if line.startswith("["):
                currentsection = line[1:-1]
                contents[currentsection] = []
            else:
                contents[currentsection].append(line)
    return contents

def rendercontents(contents, startsection):
    returnlist = []
    for line in contents[startsection]:
        if line.startswith("<"):
            returnlist.extend(rendercontents(contents, line[2:]))
        else:
            returnlist.append(line)
    return returnlist

>>> newlist = rendercontents(renderfile("yourfile"), "main")
>>> newlist
['a', 'b', 'x', 'q', 'w', 'e', 'y', 'z', 'c']
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜