I have a dictionary such as this created using Python.
d = {'a': ['Adam', 'Book', 4], 'b': ['Bill', 'TV', 6, 'Jill', 'Sports', 1, 'Bill', 'Computer', 5], 'c': ['Bill', 'Sports', 3], 'd': ['Quin', 'Computer', 3, 'Adam', 'Computer', 3], 'e': ['Quin', 'TV', 2, 'Quin', 'Book', 5], 'f': ['Adam', 'Computer', 7]}
I wanted to print this out in a sideways tree format rather on the console. I've tried pretty print but when the dictionary gets long, it becomes difficult to read.
For example, with this dictionary, it would return:
a -> Book -> Adam -> 4
b -> TV -> Bill -> 6
-> Sports -> Jill -> 1
-> Computer -> Bill -> 5
c -> Sports -> Bill -> 3
d -> Computer -> Quin -> 3
-> Adam -> 3
e -> TV -> Quin -> 2
Book -> Quin -> 5
f -> Computer -> Adam -> 7
Essentially, the pretty print is organized by the Activity, or the item in second position in the list, then by name and then by the number.
The sample output above is just an example. I tried working with Pretty print a tree but was unable to figure out how to turn that into a sideways format.
You can have a look at the code of the ETE toolkit. The function _asciiArt produces nice representations of trees even with internal node labels
from ete2 import Tree
t = Tree("(((A,B), C), D);")
print t
# /-A
# /---|
# /---| \-B
# | |
#----| \-C
# |
# \-D
Here's how I would do it. Since the tree is only two levels deep -- despite what your desired output format might seem to imply -- there's no need to use recursion to traverse its contents, as iteration works quite well. Probably this is nothing like the #f code you referenced, since I don't know the language, but it's a lot shorter and more readable -- at least to me.
from itertools import izip
def print_tree(tree):
for key in sorted(tree.iterkeys()):
data = tree[key]
previous = data[0], data[1], data[2]
first = True
for name, activity, value in izip(*[iter(data)]*3): # groups of three
activity = activity if first or activity != previous[1] else ' '*len(activity)
print '{} ->'.format(key) if first else ' ',
print '{} -> {} -> {}'.format(activity, name, value)
previous = name, activity, value
first = False
d = {'a': ['Adam', 'Book', 4],
'b': ['Bill', 'TV', 6, 'Jill', 'Sports', 1, 'Bill', 'Computer', 5],
'c': ['Bill', 'Sports', 3],
'd': ['Quin', 'Computer', 3, 'Adam', 'Computer', 3],
'e': ['Quin', 'TV', 2, 'Quin', 'Book', 5],
'f': ['Adam', 'Computer', 7]}
print_tree(d)
Output:
a -> Book -> Adam -> 4
b -> TV -> Bill -> 6
Sports -> Jill -> 1
Computer -> Bill -> 5
c -> Sports -> Bill -> 3
d -> Computer -> Quin -> 3
-> Adam -> 3
e -> TV -> Quin -> 2
Book -> Quin -> 5
f -> Computer -> Adam -> 7
Update
To organize the output by name instead of activity you'd need to change three lines as indicated below:
from itertools import izip
def print_tree(tree):
for key in sorted(tree.iterkeys()):
data = tree[key]
previous = data[0], data[1], data[2]
first = True
for name, activity, value in sorted(izip(*[iter(data)]*3)): # changed
name = name if first or name != previous[0] else ' '*len(name) # changed
print '{} ->'.format(key) if first else ' ',
print '{} -> {} -> {}'.format(name, activity, value) # changed
previous = name, activity, value
first = False
Output after modification:
a -> Adam -> Book -> 4
b -> Bill -> Computer -> 5
-> TV -> 6
Jill -> Sports -> 1
c -> Bill -> Sports -> 3
d -> Adam -> Computer -> 3
Quin -> Computer -> 3
e -> Quin -> Book -> 5
-> TV -> 2
f -> Adam -> Computer -> 7
def treePrint(tree):
for key in tree:
print key, # comma prevents a newline character
treeElem = tree[key] # multiple lookups is expensive, even amortized O(1)!
for subElem in treeElem:
print " -> ", subElem,
if type(subElem) != str: # OP wants indenting after digits
print "\n " # newline and a space to match indenting
print "" # forces a newline