[Tutor] Sort a list following the order of other list

jfouhy@paradise.net.nz jfouhy at paradise.net.nz
Tue Aug 23 01:07:22 CEST 2005


Quoting Jonas Melian <jonasmg at SoftHome.net>:

> best = [ [1024, 768], [800, 600], [640, 480] ] (it's larger)
> 
> modes = [
> (24, [1280, 1024]),
> (24, [1024, 768]),
> (24, [640, 480]),
> (16, [1600, 1200]),
> (16, [1280, 1024]),
> (15, [320, 200]),
> ]
> 
> I want to create a list with ALL elements of 'modes', but following the
> order of list 'best' (if exist the number). At the end the rest of 
> numbers in modes, are added too. And all this for each modes[0] (24, 16,
> 15, ...)

I well understand the desire to do everything in a single beautiful list
comprehension, but sometimes we have to go back to old-style programming and
actually write a function :-)

in 2.3, sort() takes an optional comparison function as a parameter. cmp(x,y)
should return <0 if x<y, 0 if x==y, and >0 if x>y.

>>> best = [ [1024, 768], [800, 600], [640, 480] ]
>>> modes = [ (24, [1280, 1024]), (24, [1024, 768]), (24, [640, 480]), (16,
[1600, 1200]), (16, [1280, 1024]), (15, [320, 200]) ]
>>> def modeCompare(m1, m2):
...  r1 = m1[1]; r2 = m2[1]
...  if r1 in best:
...   if r2 in best:
...    return cmp(best.index(r1), best.index(r2))
...   else:
...    return -1
...  else:
...   if r2 in best:
...    return 1
...   else:
...    return 0
...
>>> sorted(modes, cmp=modeCompare)
[(24, [1024, 768]), (24, [640, 480]), (24, [1280, 1024]), (16, [1600, 1200]),
(16, [1280, 1024]), (15, [320, 200])]

...mind you, having said that, here is a list comprehension solution anyway:

>>> [(b, r) for r in best for b, r2 in modes if r == r2] + [m for m in modes if
m[1] not in best]
[(24, [1024, 768]), (24, [640, 480]), (24, [1280, 1024]), (16, [1600, 1200]),
(16, [1280, 1024]), (15, [320, 200])]

HTH!

-- 
John.


More information about the Tutor mailing list