l = []
entries = {}
for id, fid, title in t:
entries[id] = entry = {'id': id, 'fid': fid, 'title': title}
if fid == -1:
l.append(entry)
else:
parent = entries[fid]
parent.setdefault('son', []).append(entry)
Здесь entries
отслеживает все записи, которые были созданы до сих пор, так что вы можете добавить «сыновей» к ним напрямую, без необходимости искать дерево.
Предполагается, что ваш список t
правильно сортируется по id
и этим сыновьям всегда являются дети нижних ids.
Демо:
>>> from pprint import pprint
>>> t = (
... (1, -1, 'python'),
... (2, -1, 'ruby'),
... (3, -1, 'php'),
... (4, -1, 'lisp'),
... (5, 1, 'flask'),
... (6, 1, 'django'),
... (7, 1, 'webpy'),
... (8, 2, 'rails'),
... (9, 3, 'zend'),
... (10, 6, 'dblog')
...)
>>> l = []
>>> entries = {}
>>> for id, fid, title in t:
... entries[id] = entry = {'id': id, 'fid': fid, 'title': title}
... if fid == -1:
... l.append(entry)
... else:
... parent = entries[fid]
... parent.setdefault('son', []).append(entry)
...
>>> pprint(l)
[{'fid': -1,
'id': 1,
'son': [{'fid': 1, 'id': 5, 'title': 'flask'},
{'fid': 1,
'id': 6,
'son': [{'fid': 6, 'id': 10, 'title': 'dblog'}],
'title': 'django'},
{'fid': 1, 'id': 7, 'title': 'webpy'}],
'title': 'python'},
{'fid': -1,
'id': 2,
'son': [{'fid': 2, 'id': 8, 'title': 'rails'}],
'title': 'ruby'},
{'fid': -1,
'id': 3,
'son': [{'fid': 3, 'id': 9, 'title': 'zend'}],
'title': 'php'},
{'fid': -1, 'id': 4, 'title': 'lisp'}]
Если «груда-приходит-после-ид» предположение не выдерживает, вам нужно добавить очередь детей идентификаторами для обработки еще:
l = []
entries = {}
queue = {}
for id, fid, title in t:
entries[id] = entry = {'id': id, 'fid': fid, 'title': title}
if id in queue:
entry['sons'] = queue[id]
del queue[id]
if fid == -1:
l.append(entry)
elif fid in entries:
parent = entries[fid]
parent.setdefault('son', []).append(entry)
else:
queue.setdefault(fid, []).append(entry)
if queue:
raise ValueError('No entries found for fid(s) {}'.format(queue.keys()))
Теперь порядок записей в t
может быть совершенно случайным образом:
>>> import random
>>> t = list(t)
>>> random.shuffle(t)
>>> l = []
>>> entries = {}
>>> queue = {}
>>> for id, fid, title in t:
... entries[id] = entry = {'id': id, 'fid': fid, 'title': title}
... if id in queue:
... entry['sons'] = queue[id]
... del queue[id]
... if fid == -1:
... l.append(entry)
... elif fid in entries:
... parent = entries[fid]
... parent.setdefault('son', []).append(entry)
... else:
... queue.setdefault(fid, []).append(entry)
...
>>> if queue:
... raise ValueError('No entries found for fid(s) {}'.format(queue.keys()))
...
>>> pprint(l)
[{'fid': -1,
'id': 1,
'son': [{'fid': 1, 'id': 7, 'title': 'webpy'},
{'fid': 1, 'id': 5, 'title': 'flask'},
{'fid': 1,
'id': 6,
'sons': [{'fid': 6, 'id': 10, 'title': 'dblog'}],
'title': 'django'}],
'title': 'python'},
{'fid': -1,
'id': 2,
'son': [{'fid': 2, 'id': 8, 'title': 'rails'}],
'title': 'ruby'},
{'fid': -1,
'id': 3,
'son': [{'fid': 3, 'id': 9, 'title': 'zend'}],
'title': 'php'},
{'fid': -1, 'id': 4, 'title': 'lisp'}]
fid
может, быть любым id
, при условии, что этот идентификатор называется где-то в последовательности t
или -1
для корневых записей.
Вы пытались написать какой-либо код? Если у вас есть, отправьте свою попытку и результат, который она создает. – rabs
Откуда вы знаете, кто является родителем? – bereal
@bereal: предположительно второе значение в кортеже –