Search code examples
pythondictionaryright-justified

Python: right justified and ordered dict


Following is my code:

inv = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1}

x=max(inv, key=lambda x: len(x.split()))
y=len(x)

#print(y)

n = "-"

q = n * (y+5)

#print(q)
#print("")

def print_table(inventory, order=None):

    if order=="count,asc":
        for key, value in sorted(inventory.iteritems(), key=lambda (k, v): (v, k)):
            print "%s %s" % (value, key)

print_table(inv,"count,asc")

I want to have something like this:

Inventory:
 count    item name
   ----------------
    45    gold coin
    12        arrow
     6        torch
     2       dagger
     1         rope
     1         ruby
    ----------------
  Total number of items: 67

Order parameter must be a string, which works as following: empty (by default) means the table is unordered "count,desc" table is ordered by count (of items in the inventory) in descending order and "cound,asc" in ascending order

I wrote function that's finding longest string in each of the inner lists to know how wide should be column to fit all strings, but now I'm stuck at this point, what should I do now?


Solution

  • You have the right idea to find the longest key and its length. All you need is to format it:

    def print_table(inventory, order=None):
        longest_key = max(inventory, key=len)
        max_width = len(longest_key)
    
        if order == "count,asc":
            for key, value in sorted(inventory.iteritems(), key=lambda (k, v): (v, k)):
                print '%6d %*s' % (value, max_width, key)
    

    Output:

         1    dagger
         1      rope
         6     torch
        42 gold coin
    

    Update

    To address different sort columns and order (ascending, descending), I would like to suggest not passing in a string, but a key function and sort direction (ascending or descending):

    def print_table(inventory, order=None, descending=False):
        longest_key = max(inventory, key=len)
        max_width = len(longest_key)
    
        for key, value in sorted(inventory.iteritems(), key=order, reverse=descending):
            print '%6d %*s' % (value, max_width, key)
    
    # Define a bunch of key functions, used for sorting
    by_count = lambda (k, v): (v, k)
    by_name = None
    
    inv = {'rope': 1, 'torch': 6, 'gold coin': 42, 'dagger': 1}
    
    print '\nBy count, ascending'
    print_table(inv, order=by_count)
    
    print('\nBy name, descending')
    print_table(inv, order=by_name, descending=True)
    

    Note: By default, the sorted function will sort a dict.items() by (k, v), so the by_name function can be None, or it can be a more explicit lambda (k, v): (k, v)