sorting values in dict

Tim Peters tim.one at home.com
Sat Jun 16 02:52:01 EDT 2001


[Victor Muslin]
> This may not be the shortest or most efficient, but it does the trick:
>
> a={'a':9,'b':8,'c':7}
> l=[]
> for k,v in a.items():
>   l.append((v,k))
> l.sort()
> for v,k in l:
>   print v,k

[Bengt Richter]
> Nobody seems to be doing it my way:

That's because they've been brainwashed <wink>.

> def sortedItemsOfDir(d,dir='a'):	#'d'escending else default
> 	if dir=='d':
> 		def cmpi(x,y):	#descending
> 			if x[1]>y[1]: return -1
> 			if x[1]<y[1]: return 1
> 			return 0

Note that hard tab characters display differently in different news and mail
readers, so it's better to stick to spaces for posted code.

With that out of the way, note that cmpi is easier written:

    def cmpi(x, y):
        return cmp(y[1], x[1])

That is, you're simulating "by hand" what cmp() does for you; no need.

> 	else:
> 		def cmpi(x,y):	#descending
> 			if x[1]>y[1]: return 1
> 			if x[1]<y[1]: return -1
> 			return 0

Likewise:

    def cmpi(x, y):
        return cmp(x[1], y[1])

You probably shouldn't have a "#descending" comment on both <wink>.

> 	items = d.items()
> 	items.sort(cmpi)
> 	return items

The reason people don't *usually* post this kind of solution is fear of
sloth:  the compare function will get called about N*log2(N) times, and
calling a Python function that often is expensive.  The decorator pattern
(building a list of tuples, sorting that directly, then undecorating) takes
O(N) operations on each end to decorate and undecorate, but as N grows large
that's insignificant compared to the N*log2(N) Python-level calls saved
during the sort.  Tuple comparison proceeds at C speed, and a Python
function call is typically much more expensive than a comparison.

That said, I pass functions to list.sort() all the time -- but, when I do,
I'm very careful not to complain to myself about the speed <wink>.

speed-is-for-speeders-ly y'rs  - tim





More information about the Python-list mailing list