我有一个类似的文件,分为这样的部分:
[main]
a
b
< sectionA
c
[sectionA]
x
< sectionB
y
z
[sectionB]
q
w
e
我想用sectionA中的内容替换"<sectionA",依此类推。最终结果应该是一个只有正确顺序的元素的列表,如下所示:['a','b','x','q','w','e','y','z','c']
A制作了下面的代码,用列表填充字典中的文件,但顺序不是我在插入时使用的顺序(所以我不确定从哪里开始)。
我也不知道用实际列表中的内容替换"<sectionA"内容的最佳方法。。。
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)
结果是:{'main':[‘a’,'b','<sectionA','c'],'sectionB':['q','w','e'],'ssectionA]:['x','<sectionB],'y','z']}
我为您制作了一些疯狂的代码:
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)
由于join
函数在右侧列表中插入代码,因此如果需要在两个或多个位置计算列表,则不必多次计算。:)
使用OrderedDict,您总是从正确的列表开始。
这并没有那么难。这就是算法:
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.
我用两个函数解决了您的问题。第一个用于将输入文件(renderfile(filename)
)呈现到Python字典中,第二个用于将内容与具有起始节(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']