2010-03-31 34 views
1

我试图将工具的输出解析到数据结构中,但我在正确地解决某些问题时遇到了一些困难。该文件是这样的:在Python中分析具有层级结构的文件

Fruits 
    Apple 
    Auxiliary 
    Core 
    Extras 
    Banana 
    Something 
    Coconut 
Vegetables 
    Eggplant 
    Rutabaga 

你可以看到,顶级项目是由一个空格缩进,以及由两个空格每个级别缩进的项目之下。这些项目也按字母顺序排列。

如何将文件转换为类似["Fruits", "Fruits/Apple", "Fruits/Banana", ..., "Vegetables", "Vegetables/Eggplant", "Vegetables/Rutabaga"]的Python列表?

回答

3
>>> with open("food.txt") as f: 
...  res = [] 
...  s=[] 
...  for line in f: 
...   line=line.rstrip() 
...   x=len(line) 
...   line=line.lstrip() 
...   indent = x-len(line) 
...   s=s[:indent/2]+[line] 
...   res.append("/".join(s)) 
...  print res 
... 
['Fruits', 'Fruits/Apple', 'Fruits/Apple/Auxiliary', 'Fruits/Apple/Core', 'Fruits/Apple/Extras', 'Fruits/Banana', 'Fruits/Banana/Something', 'Fruits/Coconut', 'Vegetables', 'Vegetables/Eggplant', 'Vegetables/Rutabaga'] 
+0

太棒了。非常好地完成。 – naivnomore 2010-03-31 17:02:59

1

所以你不想要最深层次的权利?我不知道如果我让你正确的,但尽管如此,这里有一个方法

d=[] 
for line in open("file"): 
    if not line.startswith(" "): 
     if line.startswith(" "): 
      d.append(p+"/"+line.strip()) 
     elif line.startswith(" "): 
      p=line.rstrip() 

输出

$ ./python.py 
[' Fruits/Apple', ' Fruits/Banana', ' Fruits/Coconut', ' Vegetables/Eggplant', ' Vegetables/Rutabaga'] 
+0

嗯,对不起。我想要所有的关卡,并且它可以是任意深度的。 – 2010-03-31 16:24:26

0

这里假设你的输入文件是“datafile.txt”,你只用空格缩进,您可以指定每个级别的indent_string,并且您的级别0在没有任何缩进的情况下启动(所有缩进都不会有空格)。所有这些限制都可以通过很少的努力来消除。 但基本的布局应该是清楚的:

import re 

indent_string = ' ' 
pattern = re.compile('(?P<blanks>\s*)(?P<name>.*)') 


f = open('datafile.txt') 

cache={} 

for line in f: 
    m = pattern.match(line) 
    d = m.groupdict() 
    level = len(d['blanks'])/len(indent_string) 
    cache.update({level: d['name']}) 
    s = '' 
    for i in xrange(level+1): 
    s += '/' + cache[i] 
    print s 
0

你可以做这样的事情:

builder, outlist = [], [] 
current_spacing = 0 

with open('input.txt') as f: 
    for line in f: 
     stripped = line.lstrip() 
     num_spaces = len(line) - len(stripped) 
     if num_spaces == current_spacing: 
      builder.pop() 
     elif num_spaces < current_spacing: 
      for i in xrange(current_spacing - num_spaces): 
       builder.pop() 
     builder.append(stripped) 
     current_spacing = num_spaces 
     outlist.append("/".join(builder)) 

print outlist 
相关问题