Search code examples
pythontheory

"Flat is better than nested" - for data as well as code?


This question got me thinking: should we apply the principle that "flat is better than nested" to data as well as to code? Even when there is a "logical tree structure" to the data?

In this case, I suppose it would mean representing children as a list of IDs, rather than an actual list of children, with all the nodes in a single list:

[ {'id': 4, 'children': ()},
  {'id': 2, 'children': (1, 7)},
  {'id': 1, 'children': (6, 5)},
  {'id': 6, 'children': ()},
  {'id': 5, 'children': ()},
  {'id': 7, 'children': (3,)},
  {'id': 3, 'children': ()} ]

(I used tuples because I prefer not to give myself the flexibility to mutate an object until that flexibility proves itself to be useful and usable in a clear manner. In any case I would never use None here instead of an empty sequence, because it complicates the logic, and "special cases aren't special enough" - here, it isn't special at all.)

Certainly this is shorter, but the tree structure is obscured. Does that contradict "explicit is better than implicit"?

Personally I find that "flat is better than nested" is of limited applicability, and nowhere near the most important aspect of the Zen. (Certainly I could not do a lot of the nice functional-programming things that I do if I didn't allow myself significant nesting.) I suspect that the problem with "nested" is that it requires context switching when you comprehend the information. I really think this is more of a problem when following imperative logic than for parsing data or functional-style code - where it's easier to just mentally name the nested block, and consider its workings separately from the outer context.

What say you?


Solution

  • I wouldn't inherently prefer either, but rather use whatever seems best suited to the task.

    If the structure is important, nesting makes life simple. If you're regularly operating over each node, the flat structure makes it easy to use for node in tree. Of course, if you define your own class, its easy enough to abstract it so both options are simple; but it may be harder to use with external systems, such as converting to JSON.