#python #parsing #tree
Вопрос:
У меня есть csv-файл, который выглядит как дерево (в файле 3000 строк).
A,
,B
,,B1
,,B2
,,,,,B2a
,C
,,C1
,,,C1a
,,C2
,,,,,C2a1a
Я хотел бы проанализировать файл, чтобы получить таблицу, которая выглядит следующим образом
Parent Child
A B
B B1
B B2
B2 B2a
A C
C C1
C1 C1a
C C2
C2 C2a1a
Обратите внимание, что лист со значениями B2a и C2a1a содержит больше запятых, но связан с ближайшим отцом
Комментарии:
1. что вы пробовали? покажите свой код
Ответ №1:
вы можете попробовать yaml
import yaml
import re
import io
s = """A,
,B
,,B1
,,B2
,,,,,B2a
,C
,,C1
,,,C1a
,,C2
,,,,,C2a1a"""
s_ = re.sub(r'(,*[wd] )', r'1:', s)
parsed = yaml.load(io.StringIO(s_.replace(',', ' ')))
def flatten_and_print(d):
for k,v in d.items():
if (isinstance(v, dict)):
for k2 in v:
print(k, k2)
flatten_and_print(v)
flatten_and_print(parsed)
# A B
# A C
# B B1
# B B2
# B2 B2a
# C C1
# C C2
# C1 C1a
# C2 C2a1a
Ответ №2:
Для этого вы можете использовать стек, который поддерживает путь от корня до текущего узла из входных данных.
Поскольку, по-видимому, количество запятых может увеличиваться более чем на 1, стек должен включать глубину каждого элемента, который он хранит.
Вот реализация:
def pairs(csv):
stack = []
for line in csv.splitlines():
name = line.lstrip(",")
depth = len(line) - len(name)
name = name.rstrip(",")
while stack and depth <= stack[-1][0]:
stack.pop()
if stack:
yield stack[-1][1], name
stack.append((depth, name))
Вот как вы могли бы это назвать:
csv = """A,
,B
,,B1
,,B2
,,,,,B2a
,C
,,C1
,,,C1a
,,C2
,,,,,C2a1a"""
for pair in pairs(csv):
print(*pair)