Sorting dictionary by 'sub' value

Steven Bethard steven.bethard at gmail.com
Tue Mar 8 13:34:29 EST 2005


Rory Campbell-Lange wrote:
> Thank you all very much for your help.
> 
> I did the following and it works:
> 
>     imgs=v.keys()
>     imgs.sort(lambda a,b: cmp(
>               time.strptime(str(v[a][9]['date']), '%Y:%m:%d %H:%M:%S'),
>               time.strptime(str(v[b][9]['date']), '%Y:%m:%d %H:%M:%S'))
>              )
>     for i in imgs:
>         ...

Cool.  If you ever find that this is a speed problem, it's worth 
pointing out that the decorate-sort-undecorate pattern is usually 
slightly faster:

------------------------------ test.py ------------------------------
import datetime
import time

# returns data in a similar format to yours
def get_data(n):
     today = datetime.datetime(2005, 3, 8)
     deltas = [datetime.timedelta(seconds=1e6*i)
               for i in xrange(-n, n)]
     times = [(today + delta).strftime('%Y:%m:%d %H:%M:%S')
              for delta in deltas]
     return dict([(i, {9:{'date':time}})
                  for i, time in enumerate(times)])

def sortcmp(data):
     imgs = data.keys()
     imgs.sort(lambda a,b: cmp(
               time.strptime(str(data[a][9]['date']),
                             '%Y:%m:%d %H:%M:%S'),
               time.strptime(str(data[b][9]['date']),
                             '%Y:%m:%d %H:%M:%S'))
              )
     return imgs

def sortdsu(data):
     decorated = [(time.strptime(str(data[key][9]['date']),
                                 '%Y:%m:%d %H:%M:%S'), key)
                  for key in data]
     decorated.sort()
     return [key for date, key in decorated]

# Requires 2.4
def sortkey(data):
     def value(key):
         return time.strptime(str(data[key][9]['date']),
                              '%Y:%m:%d %H:%M:%S')
     return sorted(data, key=value)
---------------------------------------------------------------------

And the timing results:

[D:\Steve]$ python -m timeit -s "import test; d = test.get_data(1000)" 
"test.sortcmp(d)"
10 loops, best of 3: 274 msec per loop

[D:\Steve]$ python -m timeit -s "import test; d = test.get_data(1000)" 
"test.sortdsu(d)"
10 loops, best of 3: 131 msec per loop

# Requires 2.4

[D:\Steve]$ python -m timeit -s "import test; d = test.get_data(1000)" 
"test.sortkey(d)"
10 loops, best of 3: 131 msec per loop

HTH,

STeVe



More information about the Python-list mailing list