Advertisement
Guest User

Untitled

a guest
Apr 20th, 2019
116
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.58 KB | None | 0 0
  1. def tree_to_list(items, sort_by=None, omit=[], reverse=False):
  2.  
  3. # First set up some empty arrays to hold interim values
  4. items_flat = []
  5. roots = []
  6. items_sorted = []
  7. items_keyed_by_id = {}
  8.  
  9. # Create a flat list of all given items
  10. for item in items:
  11. items_flat.append({
  12. 'obj': item,
  13. 'children': [],
  14. 'depth': 0,
  15. })
  16.  
  17. # Create a dict of all items keyed by ID
  18. for item in items_flat:
  19. items_keyed_by_id[item['obj'].id] = item
  20.  
  21. # Fill up the "children" attribute for every node, and the list of roots
  22. for item in items_flat:
  23. if item['obj'].parent and item['obj'].parent.id in items_keyed_by_id:
  24. parent = items_keyed_by_id[item['obj'].parent.id]
  25. parent['children'].append(item)
  26. else:
  27. roots.append(item)
  28.  
  29. # Sort the roots by the given attribute
  30. if sort_by:
  31. roots = sorted(roots, key=lambda k: getattr(k['obj'], sort_by), reverse=reverse)
  32.  
  33. # Build items_sorted by iterating through roots, adding sorted children, setting the depth, and
  34. # moving each child node into the roots to process before popping it off the stack
  35. while len(roots):
  36. root = roots[0]
  37. del roots[0]
  38.  
  39. if not omit or not root.obj.id in omit:
  40. items_sorted.append(root)
  41. children = sorted(root['children'], key=lambda k: getattr(k['obj'], sort_by), reverse=not reverse)
  42. for child in children:
  43. child['depth'] = root['depth'] + 1
  44. roots.insert(0, child)
  45.  
  46. return items_sorted
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement