2012-09-04 11 views
5

Mam słownik taki jak ten stworzony przy pomocy Pythona.Dość wydruk wyjściowy w formacie drzewa z boku w oknie konsoli

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]} 

Chciałem wydrukować to w formacie drzewa na boki zamiast na konsoli. Próbowałem ładnego druku, ale gdy słownik się wydłuża, czytanie staje się trudne.

Na przykład, z tego słownika, to wróci:

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 

Zasadniczo dość druku jest organizowany przez czyny lub pozycji w drugą pozycję na liście, a następnie według nazwy, a następnie przez numer.

Wyjście próbki powyżej jest tylko przykładem. Próbowałem pracować z Pretty print a tree, ale nie mogłem wymyślić, jak zmienić to na format boczny.

Odpowiedz

1
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 
+0

wygląda dobrze ... w dowolny sposób, aby to podobny do ładnego drzewa druku jednej gdzie ma format drzewo? – user1530318

+0

Jeśli szukasz jakiegoś rodzaju rekursywnego rozwiązania dogłębnego dla drzewa, możesz mieć podstawowy przypadek, w którym dane nie będą podlegały iteracji, w przeciwnym razie będą rekurencyjne. Nie znam modułu Pprint bardzo dobrze, więc naprawdę nie wiem, co masz nadzieję, że mogę zrobić. – rsegal

+0

Używanie nazwy słowa kluczowego takiego jak 'dict' dla argumentu lub nazwy zmiennej jest uważane za zły formularz, podobnie jak sprawdzanie typu. – martineau

3

Oto jak to zrobić. Ponieważ drzewo ma tylko dwa poziomy głębokości - pomimo tego, co wydaje się sugerować format docelowy - nie ma potrzeby używania rekurencji do przechodzenia przez jego zawartość, ponieważ iteracja działa całkiem dobrze. Prawdopodobnie nie przypomina to kodu #f, do którego się odwołujesz, ponieważ nie znam tego języka, ale jest znacznie krótszy i bardziej czytelny - przynajmniej dla mnie.

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) 

wyjściowa:

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 

Aktualizacja

Aby zorganizować wyjście po imieniu zamiast aktywności trzeba by zmienić trzy linie, jak wskazano poniżej:

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 

Dane wyjściowe po modyfikacji:

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 
+0

wiersz 3 powinien być danymi = drzewo [klucz], a nie d [klucz], prawda? – user1530318

+0

Również, jak bym to zrobił, gdybym chciał, żeby był zorganizowany przez nazwę, a nie przez działanie, tak zorganizowane przez pierwszy element na liście, a nie przez drugi. a -> adam -> książka -> 4 na przykład – user1530318

+0

Tak, linia 3 była zła (pozostałość sprzed wykonania funkcji). Naprawiłem to tak samo, jak zaktualizowałem moją odpowiedź, aby pokazać ją na gorąco, aby zmodyfikować ją tak, aby uporządkować dane wyjściowe według nazwy, a nie według aktywności. – martineau