Created
January 28, 2018 10:00
-
-
Save gruzovator/da5cab1cb2679073428d9cc7af02690e to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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