Simple tool/library to visualize huge python dict Simple tool/library to visualize huge python dict tkinter tkinter

Simple tool/library to visualize huge python dict


I do not know of a ready-to-use tool, but you could use Traits UI to swiftly develop your own

from enthought.traits.api \    import HasTraits, Instancefrom enthought.traits.ui.api \    import View, VGroup, Item, ValueEditorclass DictEditor(HasTraits):    Object = Instance( object )    def __init__(self, obj, **traits):        super(DictEditor, self).__init__(**traits)        self.Object = obj    def trait_view(self, name=None, view_elements=None):        return View(          VGroup(            Item( 'Object',                  label      = 'Debug',                  id         = 'debug',                  editor     = ValueEditor(),                  style      = 'custom',                  dock       = 'horizontal',                  show_label = False            ),          ),          title     = 'Dictionary Editor',          width     = 800,          height    = 600,          resizable = True,        )def build_sample_data():    my_data = dict(zip(range(10),range(10,20)))    my_data[11] = dict(zip(range(10),range(10,20)))    my_data[11][11] = dict(zip(range(10),range(10,20)))    return my_data# Testif __name__ == '__main__':    my_data = build_sample_data()    b = DictEditor(my_data)    b.configure_traits()

That's it. You will have a GUI like:

Traits UI uses the Model-View-Controller approach to create GUI without having the need to programatically create every widget. Here, I use the predefined ValueEditor to display arbitrary types. You can now extend it to support searching, filtering etc...screenshot

EDIT

Simple extension to support filtering:

# -*- coding: utf-8 -*-"""Created on Fri Feb 22 12:52:28 2013@author: kranzth"""from enthought.traits.api \    import HasTraits, Instance, Str, on_trait_changefrom enthought.traits.ui.api \    import View, VGroup, Item, ValueEditor, TextEditorfrom copy import deepcopyclass DictEditor(HasTraits):    SearchTerm = Str()    Object = Instance( object )    def __init__(self, obj, **traits):        super(DictEditor, self).__init__(**traits)        self._original_object = obj        self.Object = self._filter(obj)    def trait_view(self, name=None, view_elements=None):        return View(          VGroup(            Item( 'SearchTerm',                  label      = 'Search:',                  id         = 'search',                  editor     = TextEditor(),                  #style      = 'custom',                  dock       = 'horizontal',                  show_label = True            ),            Item( 'Object',                  label      = 'Debug',                  id         = 'debug',                  editor     = ValueEditor(),                  style      = 'custom',                  dock       = 'horizontal',                  show_label = False            ),          ),          title     = 'Dictionary Editor',          width     = 800,          height    = 600,          resizable = True,        )    @on_trait_change("SearchTerm")    def search(self):        self.Object = self._filter(self._original_object, self.SearchTerm)    def _filter(self, object_, search_term=None):        def has_matching_leaf(obj):            if isinstance(obj, list):                return any(                        map(has_matching_leaf, obj))            if isinstance(obj, dict):                return any(                        map(has_matching_leaf, obj.values()))            else:                try:                    if not str(obj) == search_term:                        return False                    return True                except ValueError:                    False        obj = deepcopy(object_)        if search_term is None:            return obj        if isinstance(obj, dict):            for k in obj.keys():                if not has_matching_leaf(obj[k]):                    del obj[k]            for k in obj.keys():                if isinstance(obj, dict):                    obj[k] = self._filter(obj[k], search_term)                elif isinstance(obj, list):                    filter(has_matching_leaf,obj[k])        return objdef build_sample_data():    def make_one_level_dict():        return dict(zip(range(100),                        range(100,150) + map(str,range(150,200))))    my_data = make_one_level_dict()    my_data[11] = make_one_level_dict()    my_data[11][11] = make_one_level_dict()    return my_data# Testif __name__ == '__main__':    my_data = build_sample_data()    b = DictEditor(my_data)    b.configure_traits()

will give you a textbox with "filter-as-you-type". The search isn't completely correct for all cases, but you can figure out the idea.

Please note that in this sample the data in the dict are partly integers and partly strings, and both types will be found.

screenshot


I'm finally ended up with converting my data into json as @PavelAnossov suggested and using d3 Tree Layout.

enter image description here


There are some great answers already in here, but I believe this one qualifies as "simple" (it uses only python bult-in libraries tkinter and uuid).

It is based on John Gaines Jr.'s answer in another question, modified by Will Ware to support lists, modified by me to also support tuples (runs on python 3).

I've also reorganized it so that you can call the viewer with something as simple as tk_tree_view(data), passing in a dictionary (as in the example at the end).

import uuidimport tkinter as tkfrom tkinter import ttkdef j_tree(tree, parent, dic):    for key in sorted(dic.keys()):        uid = uuid.uuid4()        if isinstance(dic[key], dict):            tree.insert(parent, 'end', uid, text=key)            j_tree(tree, uid, dic[key])        elif isinstance(dic[key], tuple):            tree.insert(parent, 'end', uid, text=str(key) + '()')            j_tree(tree, uid,                   dict([(i, x) for i, x in enumerate(dic[key])]))        elif isinstance(dic[key], list):            tree.insert(parent, 'end', uid, text=str(key) + '[]')            j_tree(tree, uid,                   dict([(i, x) for i, x in enumerate(dic[key])]))        else:            value = dic[key]            if isinstance(value, str):                value = value.replace(' ', '_')            tree.insert(parent, 'end', uid, text=key, value=value)def tk_tree_view(data):    # Setup the root UI    root = tk.Tk()    root.title("tk_tree_view")    root.columnconfigure(0, weight=1)    root.rowconfigure(0, weight=1)    # Setup the Frames    tree_frame = ttk.Frame(root, padding="3")    tree_frame.grid(row=0, column=0, sticky=tk.NSEW)    # Setup the Tree    tree = ttk.Treeview(tree_frame, columns=('Values'))    tree.column('Values', width=100, anchor='center')    tree.heading('Values', text='Values')    j_tree(tree, '', data)    tree.pack(fill=tk.BOTH, expand=1)    # Limit windows minimum dimensions    root.update_idletasks()    root.minsize(root.winfo_reqwidth(), root.winfo_reqheight())    root.mainloop()if __name__ == "__main__":    # Setup some test data    data = {        "firstName": "John",        "lastName": "Smith",        "gender": "male",        "age": 32,        "address": {            "streetAddress": "21 2nd Street",            "city": "New York",            "state": "NY",            "postalCode": "10021"},        "phoneNumbers": [            {"type": "home", "number": "212 555-1234"},            {"type": "fax",             "number": "646 555-4567",             "alphabet": [                 "abc",                 "def",                 "ghi"]             }        ]}    # call it with    tk_tree_view(data)

It looks like this:

enter image description here