Python: как перебрать всю неизвестную глубину дерева?

У меня есть стратегическая проблема написания программы, выполняющей работу.

У меня есть файлы CSV, такие как:

Column1  Column 2 
-------  ---------- 
parent1 [child1, child2, child3]
parent2 [child4, child5, child6]
child1  [child7, child8]
child5  [child10, child33]
...      ...

Неизвестно, насколько глубоко будет расширен каждый элемент этих списков, и я хочу пройтись по ним.

Код:

def make_parentClass(self):
        for i in self.csv_rows_list:
            self.parentClassList.append(parentClass(i))
        # after first Parent    
        for i in self.parentClassList:
            if i.children !=[]:
                for child in i.children:
                    for z in self.parentClassList:
                        if str(child) == str(z.node_parent):
                            i.node_children.append(z)
                            self.parentClassList.remove(z)
class parentClass():
    node_children = []
    def __init__(self, the_list):
        self.node_parent = the_list[0]
        self.children = the_list[1]

Приведенный выше код может быть решением, если я найду способ повторения. Позвольте мне посмотреть, нравится ли вам вопрос и имеет ли смысл сейчас.

Выход:

Моя цель — создать древовидную структуру с помощью другого языка, но сначала мне нужно сделать этот вывод в формате JSON. Таким образом, ожидаемый результат будет примерно таким:

{
  paren1:{'child1':{'child7':{}, 'child8':{}}, 
    'child2': {},
    'child3': {},
  },
  parent2: {
      'child4':{}, 
      'child5': {
          'child10':{},
          'child33':{}
      },
      'child6':{}
  }
}

что ты уже испробовал?

h4z3 24.07.2019 14:13

JSON, опубликованный в ответе, не соответствует CSV, вы хотели использовать [] вместо {} для каждого ребенка? Кроме того, для обработки каждого элемента просто используйте рекурсивную функцию, когда у вас есть данные в правильном формате.

Isma 24.07.2019 14:15

@ h4z3 Я в основном думал о стратегии ее решения. Например. с участием циклов For, которые были невозможны. Я также думаю о написании функции, которая зацикливается на самой себе, но все еще не может сказать, как она выглядит.

jesy2013 24.07.2019 14:17

def process_item(self, item): if isinstance(item, list): for i in item: process_item(item) else: do_something_with_item(item)

Isma 24.07.2019 14:23

Код предоставлен. Спасибо

jesy2013 25.07.2019 12:38

@Исма. Сложность заключается в том, чтобы получить его «в правильном формате».

Mad Physicist 25.07.2019 18:04

@jesy2013. Я проголосовал за повторное открытие, потому что вы явно приложили к этому усилия, и я думаю, что эта проблема интересна. Однако желаемый результат не имеет смысла. Например, child1: начинает список, но открывающей скобки нет. Не могли бы вы просмотреть вывод и исправить его, чтобы он имел смысл?

Mad Physicist 25.07.2019 18:06

Кроме того, parent1:[{ открывает две скобки, но после них присутствует только ].

Mad Physicist 25.07.2019 18:16

@MadPhysicist. Большое спасибо, что проверили это и нашли проблему интересной. Вывод JSON был отредактирован, и теперь он в хорошем формате.

jesy2013 26.07.2019 09:24

Я все еще не уверен, что понимаю. Почему списки листьев, а не словари? Я думал, что дети могут быть вложены бесконечно. По крайней мере, не должны ли 'child7', 'child8' быть ключами dict, а не элементами списка? Вы можете сделать специальное исключение для значений child2, child3 (например), но это кажется нелогичным.

Mad Physicist 26.07.2019 09:27

@MadPhysicist. Сейчас хорошо, да?

jesy2013 26.07.2019 09:45

@jesy. Теперь хорошо

Mad Physicist 26.07.2019 10:18
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
13
559
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я бы рекомендовал решение с использованием двух словарей. Один вложенный с фактической структурой данных, которую вы планируете преобразовать в JSON, и один плоский, который позволит вам найти ключи. Поскольку в Python все является ссылкой, вы можете убедиться, что оба словаря имеют одинаковые значения. Тщательная модификация плоского словаря создаст для вас вашу структуру.

Следующий код предполагает, что вам уже удалось разбить каждую строку на строку parent и список children, содержащий значения из двух столбцов.

json_dict = {}
flat_dict = {}

for parent, children in file_iterator():
    if parent in flat_dict:
        value = flat_dict[parent]
    else:
        value = {}
        flat_dict[parent] = json_dict[parent] = value
    for child in children:
        flat_dict[child] = value[child] = {}

Запуск этого производит json_dict следующим образом:

{
    'parent1': {
        'child1': {
            'child7': {},
            'child8': {}
        },
        'child2': {},
        'child3': {}
    },
    'parent2': {
        'child4': {},
        'child5': {
            'child10': {},
            'child33': {}
        },
        'child6': {}
    }
}

Вот IDEОдна ссылка, с которым можно поиграть.

Большое спасибо. На самом деле это кажется мне довольно хорошим решением. Я собираюсь проверить это. Есть одна структура, которую мне нужно обработать: для меня каждая строка имеет вид ['родительский', [дочерний, дочерний, дочерний], но в вашем решении содержимое находится в кортеже.

jesy2013 26.07.2019 10:58

Это элегантный ответ для меня и довольно быстрый, но есть простая проблема, например. если Child1 и его дочерние элементы будут введены двумя родителями, его дочерние элементы появятся только у одного из родителей. например добавьте это ('parent3', ['child1', 'child2', 'child3'])

jesy2013 26.07.2019 14:39

Это совсем другой вопрос, чем вы задали. Выберите этот ответ, а затем все остальные с этим условием.

Mad Physicist 26.07.2019 17:32

Да я вижу. Я буду. Спасибо.

jesy2013 26.07.2019 19:03

Да :). Большое спасибо за вашу помощь в целом.

jesy2013 29.07.2019 15:02

@jesy2013. Я бы порекомендовал просмотреть все ваши предыдущие вопросы и выбрать ответы на них.

Mad Physicist 29.07.2019 15:04

все проверили :)

jesy2013 29.07.2019 15:34

Другие вопросы по теме