Skip to content

Instantly share code, notes, and snippets.

@gruzovator
Created January 28, 2018 10:00
Show Gist options
  • Save gruzovator/da5cab1cb2679073428d9cc7af02690e to your computer and use it in GitHub Desktop.
Save gruzovator/da5cab1cb2679073428d9cc7af02690e to your computer and use it in GitHub Desktop.
LOCATIONS = """
country
UK
city
London
Guildford
county
Surray
Sussex
Belgium
Russia
city
Moscow
federal district
Central
South
Germany
"""
import io
from itertools import takewhile
def tabtree_nodes(fileobj):
path = []
value = None
indent_step = None
depth = 0
for line_n, line in enumerate(fileobj):
line = line.rstrip()
if not line:
continue
ind = len(list(takewhile(lambda ch: ch == ' ' or ch == '\t', line)))
val = line[ind:]
# setup indentation step size
if not indent_step and ind:
indent_step = ind
# calc depth and check indentation size is correct
d, reminder = divmod(ind, indent_step or 1)
if reminder:
raise Exception('Indentation size error, line: %d' % line_n)
if d > depth:
if d - depth > 1:
raise Exception('Indentation problem, line: %d' % line_n)
path.append(value)
yield (path + [val])
elif d < depth:
path = path[:-(depth - d)]
yield (path + [val])
else:
yield (path + [val])
depth = d
value = val
def locations_tree(fileobj):
for node in tabtree_nodes(fileobj):
if len(node) % 2 == 0:
yield [dict(level=level, location=location) for level, location in zip(node[::2], node[1::2])]
for i in locations_tree(io.StringIO(LOCATIONS)):
print(i)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment