Srini Vasan
Srini Vasan

Reputation: 83

Obtaining top 2 max values from a list and finding its corresponding value from 2nd list

I am currently trying to obtain top 2 maximum values from the following list (Quant) and its corresponding value from the 2nd list (FF).

  Quant = ['1', '29', '109', '2', '1', '1', '100']
  FF = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

The top 2 max value in 1st list is 100 & 109 and its corresponding value in 2nd list is c & g. I tried to get the position of top values in Quant list by the following method.

  a = max(Quant)
  pos1 = [i for i, j in enumerate(Qu) if j == a]
  Quant.remove(a)
  b = max(Quant)
  pos2 = [i for i, j in enumerate(Qu) if j == b]
  for x, y in zip(pos1, pos2)
     FC1 = FF[x]
     FC2 = FF[y]

i am not sure if it is the correct way. The current Quant list does not contain duplication in max values. What if there are duplication and in that case pos1 will have 2 index values. If yes, In that i would need those 2 values from list 1 along with the subsequent value from list2.

Kindly assist me on the part.

Upvotes: 1

Views: 782

Answers (4)

Ruzihm
Ruzihm

Reputation: 20249

In one line, you can do this by sorting the zipped list then unzipping only the first two items:

((FC1,FC2), (pos1,pos2)) = zip(
        *sorted(zip(Quant,FF), key=lambda x:int(x[0]), reverse=True)[:2])

or if you interchange the variables, you don't even need to unzip:

((FC1,pos1), (FC2,pos2)) = sorted(zip(Quant,FF), 
        key=lambda x:int(x[0]), reverse=True)[:2]
>>> FC1
'109'
>>> FC2
'100'
>>> pos1
'c'
>>> pos2
'g'

Upvotes: 2

jdaz
jdaz

Reputation: 6053

Will the values in Quant always be strings? If you have control over it, you should make them numbers, because right now max(Quant) returns 29.

Here's one way to get what you're looking for:

Quant = ['1', '29', '109', '2', '1', '1', '100']
FF = ['a', 'b', 'c', 'd', 'e', 'f', 'g']

quantNums = [int(n) for n in Quant]

max2, max1 = sorted(zip(quantNums, FF))[-2:]

max1 # (109, 'c')
max2 # (100, 'g')

Upvotes: 1

Nicolas Gervais
Nicolas Gervais

Reputation: 36624

This would do it, I hope you find it an elegant solution:

[*map(lambda x: FF[x], map(lambda x: Quant.index(str(x)), sorted(map(int, Quant), 
    reverse=True)[:2]))]
['c', 'g']

Or this:

[FF[i] for i in map(lambda x: Quant.index(str(x)), sorted(map(int, Quant), 
    reverse=True)[:2])]

Upvotes: 1

liorr
liorr

Reputation: 800

You can achieve that using numpy,

import numpy as np

# Convert the list to numpy array
Quant = ['1', '29', '109', '2', '1', '1', '100']
Quant = np.array(Quant).astype(int)

# Get the two largest elements
ind = Quant.argsort()[-2:]

# Get the values from FF
FF = np.array(['a', 'b', 'c', 'd', 'e', 'f', 'g'])

FF[ind]

Upvotes: 0

Related Questions