我在这里看到下面的问题:
- 从文件中读取关系;
- 从关系构建层次结构。
- 将层次结构写入文件。
假设层次结构树的高度小于默认
递归限制(在大多数情况下等于
1000
),让我们为这些单独的任务定义实用函数。
Parsing of relations can be done with
def parse_relations(lines):
relations = {}
splitted_lines = (line.split() for line in lines)
for parent, child in splitted_lines:
relations.setdefault(parent, []).append(child)
return relations
Building hierarchy can be done with
Python >=3.5
def flatten_hierarchy(relations, parent='Earth'):
try:
children = relations[parent]
for child in children:
sub_hierarchy = flatten_hierarchy(relations, child)
for element in sub_hierarchy:
try:
yield (parent, *element)
except TypeError:
yield (parent, child)
except KeyError:
yield None
Python <3.5: extended iterable unpacking was added with PEP-448, but it can be replaced with itertools.chain
like
import itertools
def flatten_hierarchy(relations, parent='Earth'):
try:
children = relations[parent]
for child in children:
sub_hierarchy = flatten_hierarchy(relations, child)
for element in sub_hierarchy:
try:
yield tuple(itertools.chain([parent], element))
except TypeError:
yield (parent, child)
except KeyError:
yield None
Hierarchy export to file can be done with
def write_hierarchy(hierarchy, path, delimiter='\t'):
with open(path, mode='w') as file:
for row in hierarchy:
file.write(delimiter.join(row) + '\n')
用法
假设文件路径为 'relations.txt'
:
with open('relations.txt') as file:
relations = parse_relations(file)
给我们
>>> relations
{'Asia': ['Srilanka', 'India'],
'Srilanka': ['Colombo'],
'Continents': ['Europe', 'Asia'],
'India': ['Mumbai', 'Pune'],
'Earth': ['Continents']}
我们的层级结构是
>>> list(flatten_hierarchy(relations))
[('Earth', 'Continents', 'Europe'),
('Earth', 'Continents', 'Asia', 'Srilanka', 'Colombo'),
('Earth', 'Continents', 'Asia', 'India', 'Mumbai'),
('Earth', 'Continents', 'Asia', 'India', 'Pune')]
最后将其导出到名为
'hierarchy.txt'
的文件中:
>>> write_hierarchy(sorted(hierarchy), 'hierarchy.txt')
我们使用sorted
来获得类似于所需输出文件中的层次结构。
P. S.
如果您不熟悉Python
生成器,我们可以定义flatten_hierarchy
函数,如下:
Python >= 3.5
def flatten_hierarchy(relations, parent='Earth'):
try:
children = relations[parent]
except KeyError:
return None
result = []
for child in children:
sub_hierarchy = flatten_hierarchy(relations, child)
try:
for element in sub_hierarchy:
result.append((parent, *element))
except TypeError:
result.append((parent, child))
return result
Python < 3.5
import itertools
def flatten_hierarchy(relations, parent='Earth'):
try:
children = relations[parent]
except KeyError:
return None
result = []
for child in children:
sub_hierarchy = flatten_hierarchy(relations, child)
try:
for element in sub_hierarchy:
result.append(tuple(itertools.chain([parent], element)))
except TypeError:
result.append((parent, child))
return result