another way to sort like l.sort(key=lambda x:(x[0][0], -x[1][0]))

Terry Reedy tjreedy at udel.edu
Tue Sep 7 14:15:39 EDT 2010


On 9/7/2010 9:24 AM, sajuptpm wrote:
> I have a list of tuples.
>
> l = [((30,50),(70)), ((50,20),(20))]
>
> for i in range(10):
> 	k = ((i+30,i+50),(i+70))

The (i+70) parens do nothing, as already explained to (20)

Your set of test data are not very good as they do not test all the 
insertion possibilities. The value of the third number is not relevant 
to the problem and might as well be 0 for testing purposes.

#suppose creating new tuple in each iteration
> using some random value and in sert it into list.
>
> 	flag=True
> 	for i, v in enumerate(l):

You are reusing 'i' as index variable when it is already in use as index 
variable for the outer loop. This is a confusing and a bad idea in 
general, even if it happens to work.

> 	if v>= k:
> 	        l.insert(i,k)
> 	        flag = False
> 	        break

This block should be indented under the inner for loop

> 	if flag:
> 	l.append(k)

flay can be avoided by using else clause of for statement

> This code will give a list of tuples sorted in asc order.
> I need to change this code to sort this list by k[0][0] ascending and
> k[0][1] descending.
> What are the modifications needed in this code.

Change the v>=k test to be the one you want. Here is my code:

l = [((30,51),0), ((30,49),0), ((32,20),0)]

for i in range(5):
     k = ((i+29,i+51), 0)
     for i, v in enumerate(l):
         v00 = v[0][0]
         k00 = k[0][0]
         if v00 > k00 or v00==k00 and v[0][1] <= k[0][1]:
             l.insert(i,k)
             break
     else:
         l.append(k)

print(l)
# prints
[((29, 51), 0), ((30, 52), 0), ((30, 51), 0), ((30, 49), 0),
  ((31, 53), 0), ((32, 54), 0), ((32, 20), 0), ((33, 55), 0)]


> I dont want to user sort() method of list.

Why not? Even for the example above, .sort is faster than doing the 
insert sort in Python code! Indent the above with def f1():. Then

def f2():
     l = [((30,51),0), ((30,49),0), ((32,20),0)]

     for i in range(5):
         l.append(((i+29,i+51), 0))
     l.sort(key=lambda x:(x[0][0], -x[0][1]))

import timeit
print(timeit.timeit(f1,'from __main__ import f1,f2',number=100000))
print(timeit.timeit(f2,'from __main__ import f1,f2',number=100000))
#prints
2.51296240165
1.63514413145

> i need to implement  l.sort(key=lambda x:(x[0][0], -x[1][0])) in

That should be -x[0][1]
It is a good idea to test code before posting.

Any reason for the 'need' other than a wrong idea about relative speed?

-- 
Terry Jan Reedy




More information about the Python-list mailing list