5

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

これをコンソールではなく横向きのツリー形式で出力したかったのです。きれいに印刷してみましたが、辞書が長くなると読みにくくなります。

たとえば、このディクショナリでは、次のように返されます。

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

基本的に、プリティ プリントは、アクティビティ、またはリストの 2 番目の位置にあるアイテム、名前、番号の順で編成されます。

上記の出力例は単なる例です。Pretty print a treeで作業を試みましたが、それを横向きの形式に変換する方法がわかりませんでした。

4

3 に答える 3

8

ETE ツールキットのコードを見ることができます。関数_asciiArtは、内部ノード ラベルがあってもツリーの優れた表現を生成します

from ete2 import Tree
t = Tree("(((A,B), C), D);")
print t

#               /-A
#          /---|
#     /---|     \-B
#    |    |
#----|     \-C
#    |
#     \-D
于 2013-06-23T11:23:47.293 に答える
3

これが私がそれを行う方法です。ツリーの深さは 2 レベルしかないため (目的の出力形式が暗示するように見えるかもしれませんが)、反復が非常にうまく機能するため、再帰を使用してその内容をトラバースする必要はありません。私は言語を知らないので、おそらくこれはあなたが参照した #f コードのようなものではありませんが、少なくとも私にとってははるかに短くて読みやすいです。

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)

出力:

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

アップデート

アクティビティではなく名前で出力を整理するには、以下に示すように 3 行を変更する必要があります。

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

変更後の出力:

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
于 2012-09-04T09:39:12.573 に答える
0
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
于 2012-09-04T01:56:23.860 に答える