partial list sort

Terry Reedy tjreedy at udel.edu
Wed Oct 9 14:50:00 CEST 2002


"jsaul" <jsaul at gmx.de> wrote in message
news:20021009094141.GA852 at jsaul.de...
> Hi there,
>
> I am looking for the proper way to sort a list range-wise. The
> scenario is as follows: I am reading a list of data elements
> triple-wise component A, B and C, then the next triple A, B, C and
> so on.  Each list element has a component identifier which takes
> the values "A", "B", or "C". What I want is to sort the components
> within each *triple*, but *not* the while list, so that I can
> assure an order of A-B-C no matter what the original order in the
> data was, which can as well be B-C-A or whatever.
>
> Here is a simplified version of my script illustrating the
> problem:
>
>     list=[ [1,'C'], [2,'B'], [3,'A'], [4,'C'], [5,'B'], [6,'A'] ]
>     print list

Don't use list as a variable name.  It is a builtin type name.  I will
call this lis3.

>     def sort_components (list):
> def cmp_comp (data1, data2):
>     if   data1[1] == data2[1]:  return  0
>             elif data1[1]  < data2[1]:  return -1
>     return 1
>         print list
> list.sort(cmp_comp)
>         print list
> return

Tabs are bad for Usenet posting if you want stupid people like me who
use Outlook Express to read posted code.

>     for k in range(0, len(list), 3):
> # sort over ranges:
>         sort_components(list[k:k+3])

for k in range(0, len(lis3), 3): #not tested
  tem = lis3[k:k+3]
  sort_components(tem)
  lis3[k:k+3] = tem
...
> want    [[3, 'A'], [2, 'B'], [1, 'C'], [6, 'A'], [5, 'B'], [4, 'C']]
...
> Can anybody give me a hint about what I have overlooked?

That you must copy sorted slice back into list.

All of this would be much easier if list were organized as list of
explicit triples and if pairs had sort key first.  IE (tested)

lis3=[ [['C',1], ['B',2], ['A',3]], [['C',4], ['B',5], ['A',6]] ]
for triple in lis3:
  triple.sort()

>>> lis3
[[['A', 3], ['B', 2], ['C', 1]], [['A', 6], ['B', 5], ['C', 4]]]

Since you presumably want to process triples after sorting, I would
suggest going this route.  IE
>>> listin=[ [1,'C'], [2,'B'], [3,'A'], [4,'C'], [5,'B'], [6,'A'] ]
>>> for item in listin: item.reverse()
...
>>> listin
[['C', 1], ['B', 2], ['A', 3], ['C', 4], ['B', 5], ['A', 6]]
>>> worklist=[[listin[i],listin[i+1],listin[i+2]] for i in
range(0,len(listin),3)]
>>> worklist
[[['C', 1], ['B', 2], ['A', 3]], [['C', 4], ['B', 5], ['A', 6]]]
>>> for triple in worklist: triple.sort()
...
>>> worklist
[[['A', 3], ['B', 2], ['C', 1]], [['A', 6], ['B', 5], ['C', 4]]]

Terry J. Reedy





More information about the Python-list mailing list