river_bell
river_bell

Reputation: 25

Working with nested dictionaries and formatting for display

I have a partial answer from here Construct a tree from list os file paths (Python) - Performance dependent

My specific problem requires me to go from

this

dir/file  10  
dir/dir2/file2  20  
dir/dir2/file3  10
dir/file3  10  
dir3/file4  10  
dir3/file5  10

To

dir/  **50**     
    dir2/  **30**    
        file2  
        file3
    file
    file3  
dir3/  **20**  
    file4  
    file5  

Basically the numbers at the end are the file sizes and
I have been trying to figure out how to display the size of all the files to the parent directory

Edit:

r = re.compile(r'(.+\t)(\d+)')
    def prettify(d, indent=0):
        for key, value in d.iteritems():
            ss = 0
            if key == FILE_MARKER:
                if value:
                    for each in value:
                        mm = r.match(each)
                        ss +=  int(mm.group(2))
                        print '  ' * indent + each
                        ***print '    ' * indent  + format_size(ss)***
            else:
                print '  ' * indent + str(key)
                if isinstance(value, dict):
                    addSizes(value, indent+1)
                else:
                    print '  ' * (indent+1) + str(value)  

This is mac's answer from the above link which i edited to use regExp
Solutions that occurred to me led me to create a new dict or adding an inner function.
I have lost my whole day and wished i had asked for help earlier in the day.
Please help.

Upvotes: 0

Views: 134

Answers (2)

FMcC
FMcC

Reputation: 349

Not the most elegant thing in the world, but this should get you where you need to be. You'll need to change the tree creation function to deal with whatever form of input you are getting. Once the tree is generated it's just using a recursive tree traversal to form the output.

import re
input_dirs = """dir/file  10  
dir/dir2/file2  20  
dir/dir2/file3  10
dir/file  10  
dir3/file4  10  
dir3/file5  10
dir/dir2/dir4/file2 10"""

def create_file_tree(input_string):
    dir_dict = {}
    for file_path in input_string.split('\n'):
        path_list = re.sub('/',' ',file_path).split()
        path_list[-1] = int(path_list[-1])
        path_dict = dir_dict
        final_item = ""
        for item in path_list[:-1]:
            parent_dict = path_dict
            last_item = item
            path_dict = path_dict.setdefault(item,{})
        parent_dict[last_item] = path_list[-1]
    return dir_dict

def pretty_file_tree(file_tree):
    def traverse(sub_dict,indent=0, total=0):
        string_out = ""
        indent += 1
        for key in sorted(sub_dict.keys()):
            if type(sub_dict[key]) == dict:
                sub_total = traverse(sub_dict[key],indent,0)
                total += sub_total[0]
                string_out += '  '*indent + key + ' ' + '**' + str(sub_total[0]) + '**' + '\n' + sub_total[1]
            else:
                string_out += '  '*indent + key  + '\n'
                total += sub_dict[key]

        return total, string_out

    output_string = traverse(file_tree)
    print(output_string[1])

pretty_file_tree(create_file_tree(input_dirs))

Sorry it's not following the code you posted, but i'd begun to produce this before the edit...

Upvotes: 2

Dan Hogue
Dan Hogue

Reputation: 1

As you process the input build a string with place holders (%d) for the numbers, then print out the string.

Upvotes: 0

Related Questions