rezzz
rezzz

Reputation: 151

Sort elements of a list with two or more criteria

I have the ZZ tuple for 3 lists that each includes 7 lists. I would like to sort ZZ for each of three lists use descending order for the first element. If two first elements have the same values, I would like to first do descending order for them based on their differences. Second, if one of these lists has more cost give it priority. In the following you can see the lists:

ZZ= [[[500, 475], [500, 1307], [1500, 1476], [500, 537], [0, 527], [500, 452], [1000, 446]], [[350, 475], [700, 1307], [1050, 1476], [0, 537], [350, 527], [350, 452], [700, 446]], [[400, 475], [1200, 1307], [1200, 1476], [200, 537], [400, 527], [400, 452], [800, 446]]]
Cost=[600, 110, 35, 110, 200, 120, 80]

my code is:

YY=sorted(enumerate(ZZ[s-1]),key=lambda x: ( x[1], -x[0]), reverse=True)
index_list= [b[0] for b in sorted(enumerate(ZZ[s-1]),key=lambda x: ( x[1]),   reverse=True)]

the results of this code is:

YY = [(2, [1500, 1476]), (6, [1000, 446]), (1, [500, 1307]), (3, [500, 537]), (0, [500, 475]), (5, [500, 452]), (4, [0, 527])]

However I would have the following list:

YY = [(2, [1500, 1476]), (6, [1000, 446]), (0, [500, 475]), (5, [500, 452]), (3, [500, 537]),  (1, [500, 1307]), (4, [0, 527])]

Upvotes: 0

Views: 83

Answers (1)

Leonhard Triendl
Leonhard Triendl

Reputation: 822

If you want to sort a list based on more than one criteria, you can do this with a lamda function that returns a tuple

A small example:

ZZ= [[500, 475], [500, 1307], [1500, 1476], [500, 537], [0, 527], [500, 452], [1000, 446]]
YY = sorted(ZZ,reverse=True,key=lambda y: (y[0],y[0]-y[1]))

y[0] ist the first value and y[0]-y[1] is the difference. If you want to bring in a second list (Cost) you can combine the two lists and (if you need it) the position.

ZZ= [[500, 475], [500, 1307], [1500, 1476], [500, 537], [0, 527], [500, 452], [1000, 446]]
Cost=[600, 110, 35, 110, 200, 120, 80]
ZZc=[ZZ[z]+[Cost[z]]+[z] for z in range(len(ZZ))]
print(ZZc)

prints

[[500, 475, 600, 0], [500, 1307, 110, 1], [1500, 1476, 35, 2], [500, 537, 110, 3], [0, 527, 200, 4], [500, 452, 120, 5], [1000, 446, 80, 6]]

and now you can sort it with

YY = sorted(ZZc,reverse=True,key=lambda y: (y[0],y[0]-y[1],y[2])) 

or if you want to sort 1. Value 1, 2. Cost and 3. Difference you can sort it with:

YY = sorted(ZZc,reverse=True,key=lambda y: (y[0],y[2],y[0]-y[1]))

to get the list of tuples in your question the script would be like:

ZZ= [[[500, 475], [500, 1307], [1500, 1476], [500, 537], [0, 527], [500, 452], [1000, 446]], [[350, 475], [700, 1307], [1050, 1476], [0, 537], [350, 527], [350, 452], [700, 446]], [[400, 475], [1200, 1307], [1200, 1476], [200, 537], [400, 527], [400, 452], [800, 446]]] 
Cost=[600, 110, 35, 110, 200, 120, 80]

YY=[]
for Zi in ZZ:
    ZZi=[Zi[z]+[Cost[z]]+[z] for z in range(len(Zi))]
    YY.append(sorted(ZZi,reverse=True,key=lambda y: (y[0],y[2],y[0]-y[1])))

for Yi in YY:
    print([(y[3],[y[0],y[1]]) for y in Yi])

My original answer befor I knew that you can sort with tuples (it works but don't use ist):

You can sort it with

ZZ= [[[500, 475], [500, 1307], [1500, 1476], [500, 537], [0, 527], [500, 452], [1000, 446]], [[350, 475], [700, 1307], [1050, 1476], [0, 537], [350, 527], [350, 452], [700, 446]], [[400, 475], [1200, 1307], [1200, 1476], [200, 537], [400, 527], [400, 452], [800, 446]]] 
Cost=[600, 110, 35, 110, 200, 120, 80]

for Zi in ZZ:
    ZZi=[Zi[z]+[Cost[z]]+[z] for z in range(len(Zi))]
    YY = sorted(ZZi,reverse=True,key=lambda zlist: (int(zlist[0])*1000000)+(int(zlist[0]-zlist[1])*1000)+zlist[2])
    print [(y[3],[y[0],y[1]]) for y in YY]

Upvotes: 1

Related Questions