views:

114

answers:

5

I have a 2D dictionary in python indexed by two IPs. I want to group the dictionary by the first key.

For example, the before would look like this:

myDict["182.12.17.50"]["175.12.13.14"] = 14
myDict["182.15.12.30"]["175.12.13.15"] = 10
myDict["182.12.17.50"]["185.23.15.69"] = 30
myDict["182.15.12.30"]["145.33.34.56"] = 230

so

for key1, key2 in myDict:
     print key1 +"   " +key2 +"   " +myDict[key1, key2]

would print

182.12.17.50   175.12.13.14   14
182.15.12.30   175.12.13.15   10
182.12.17.50   185.23.15.69   30
182.15.12.30   145.33.34.56   230

But I want to sort it so it would print

182.12.17.50   175.12.13.14   14
182.12.17.50   185.23.15.69   30
182.15.12.30   175.12.13.15   10
182.15.12.30   145.33.34.56   230

Any idea how this could be accomplished?

A: 

You can pass a custom comparison function into Sorted. http://docs.python.org/library/functions.html#sorted

With it, you can specify which key to compare and how.

Ishpeck
A: 

I guess, I have not understood the problem very well.

Wouldn't the output of above dictionary look like this:

>>> myDict
{'182.12.17.50': {'185.23.15.69': 30, '175.12.13.14': 14}, '182.15.12.30': {'175.12.13.15': 10, '145.33.34.56': 230}}

and then you could use OrderedDict to create a sorted dictionary.

pyfunc
+1  A: 

Dicts have no order, but what you can get is a sorted list of items.

>>> sorted((k, sorted(v.items())) for k,v in myDict.items())
[('182.12.17.50', [('175.12.13.14', 14), ('185.23.15.69', 30)]), 
 ('182.15.12.30', [('145.33.34.56', 230), ('175.12.13.15', 10)])]
THC4k
A: 

Dictionaries are an unordered type and in your example I don't see a reason why you would want the dict to be ordered.

If you need to create an ordered series of the dictionary's contents, i.e. its items, you can do that simply by applying sorted:

# Returns sorted list of item tuples
sorted(myDict.iteritems())

Or check out OrderedDict if your Python version supports it and you know what it means to have a sorted dictionary.

AndiDog
+2  A: 

Well, there are a variety of options. One of them would be to sort the keys before printing, something like this:

for key1 in sorted(myDict):
    for key2 in myDict[key1]:
        print key1 +"   " +key2 +"   " +myDict[key1][key2]

Another option would be to use the sorteddict class from the blist module (disclaimer: I'm the author :) ), which will always return the keys in sorted order.

In either cases, since the keys are IP addresses, you might want to write a custom "key" function to pass to sort/sorted/sorteddict so they will sorted by their numeric value rather than lexicographically as a string.

Daniel Stutzbach