Reputation: 13
I dont know how to explaind this but I'll give it a try. I have a list1 = [('Lista-A', 2000), ('Lista-X', 1000), ('Lista-Z', 5000)])
then i will have a
list2 = [['Lista-A', 2000.0],
['Lista-A', 1000.0],
['Lista-A', 666.6666666666666],
['Lista-A', 500.0],
['Lista-A', 400.0],
['Lista-A', 333.3333333333333],
['Lista-X', 1000.0],
['Lista-X', 500.0],
['Lista-X', 333.3333333333333],
['Lista-X', 250.0],
['Lista-X', 200.0],
['Lista-X', 166.66666666666666],
['Lista-Z', 5000.0],
['Lista-Z', 2500.0],
['Lista-Z', 1666.6666666666667],
['Lista-Z', 1250.0],
['Lista-Z', 1000.0],
['Lista-Z', 833.3333333333334]]
Now i need to pick the n biggest items from the list2 but everytime 2 or 3 or more items have the same numeric value, the function will need to go back to the first list and check which one of its items have the smallest numeric value the from the items with equal value, it'll have to pick the one that has the same "name" (Lista-A, Z or X) as the item from the first list with the smallest numeric value. I don't if its clear what i need to do. I already tried to sort the list, but then i dont know to move on.
For this case I need the 6 biggest values, so the expected result would be
list3 = [['Lista-Z', 5000.0],
['Lista-Z', 2500.0],
['Lista-A', 2000.0],
['Lista-Z', 1666.6666666666667],
['Lista-Z', 1250.0],
['Lista-x', 1000.0]]
Upvotes: 1
Views: 44
Reputation: 82785
If i understood correctly
list1 = [('Lista-A', 2000), ('Lista-X', 1000), ('Lista-Z', 5000)]
list1 = dict(list1) #Converted to dict for easy lookup
list2 = [['Lista-A', 2000.0],
['Lista-A', 1000.0],
['Lista-A', 666.6666666666666],
['Lista-A', 500.0],
['Lista-A', 400.0],
['Lista-A', 333.3333333333333],
['Lista-X', 1000.0],
['Lista-X', 500.0],
['Lista-X', 333.3333333333333],
['Lista-X', 250.0],
['Lista-X', 200.0],
['Lista-X', 166.66666666666666],
['Lista-Z', 5000.0],
['Lista-Z', 2500.0],
['Lista-Z', 1666.6666666666667],
['Lista-Z', 1250.0],
['Lista-Z', 1000.0],
['Lista-Z', 833.3333333333334]]
list2.sort(key=lambda x: (x[1], -list1.get(x[0], x[0])), reverse=True)
print(list2[:6])
Output:
[['Lista-Z', 5000.0],
['Lista-Z', 2500.0],
['Lista-A', 2000.0],
['Lista-Z', 1666.6666666666667],
['Lista-Z', 1250.0],
['Lista-X', 1000.0]]
Upvotes: 1
Reputation: 4586
One way this can be done is with NumPy's lexsort
. First I'd map the first column to the corresponding numerical values:
>>> tiebreakers = dict(list1)
>>> arr = np.array([(tiebreakers[a], b) for (a, b) in list2])
>>> arr
array([[2000. , 2000. ],
[2000. , 1000. ],
[2000. , 666.66666667],
[2000. , 500. ],
[2000. , 400. ],
[2000. , 333.33333333],
[1000. , 1000. ],
[1000. , 500. ],
[1000. , 333.33333333],
[1000. , 250. ],
[1000. , 200. ],
[1000. , 166.66666667],
[5000. , 5000. ],
[5000. , 2500. ],
[5000. , 1666.66666667],
[5000. , 1250. ],
[5000. , 1000. ],
[5000. , 833.33333333]])
Then you can sort the array as required with lexsort
:
>>> order = np.lexsort((arr[:, 0], -arr[:, 1])) # Sorts by column 1 desc and column 0 asc
>>> order
array([12, 13, 0, 14, 15, 6, 1, 16, 17, 2, 7, 3, 4, 8, 5, 9, 10, 11])
>>> list3 = [list2[i] for i in order]
>>> list3[:6]
[['Lista-Z', 5000.0],
['Lista-Z', 2500.0],
['Lista-A', 2000.0],
['Lista-Z', 1666.6666666666667],
['Lista-Z', 1250.0],
['Lista-X', 1000.0]]
Upvotes: 1