Python: best way to iterate through lists and store which has max value for each index

Question:

In Python (3.8), I have 15 lists of the same length.

Each list contains floats.

Here for the example, I will pretend I have 3 lists of length 5 to demonstrate my problem:

List1 = [29.561801, 29.564141, 29.566480, 29.293966, 29.291252]
List2 = [26.602566, 22.752335, 22.755249, 22.754278, 22.756220]
List3 = [23.966560, 23.960471, 23.954381, 29.568819, 29.571159]

For each index, I want to find which list has the maximum value. And store the result in a new List. With my 3 example list from above, my output would be:

Result=[1, 1, 1, 3, 3]

Right now I have the following code to do this. It works, but it feels very tedious (especially since I have in reality 15 lists and not 3!).

maxValue = 0
listWithMaxValue=0
Result=[]
for i in range(len(List1)):
    maxValue=List1[i]
    listWithMaxValue=1
    if(List2[i] > maxValue):
        maxValue=List2[i]
        listWithMaxValue=2
    if(List3[i] > maxValue):
        maxValue=List3[i]
        listWithMaxValue=3
    Result=np.append(Result, listWithMaxValue)

It feels that there must be a better way to achieve the same result without repeating 15 times the same "if" loop?

Asked By: Tritize

||

Answers:

Having variables List1, List2, List3 (presumably etc) is definitely a complication. You should have a single array and loop over its indices. Then the rest should be fairly trivial.

floats = [
  [1.0] * 7,
  [2.0] * 7,
  [3.0] * 7,
  [4.0] * 7,
  [17.42] * 7,
  [6.0] * 7,
  [0.1, 12.2, 27.3, 18.4, 496.5, 7.6, 1.7]]

maxidx = []

for i in range(len(floats[0])):
    maxx = floats[0][i]
    maxi = 0
    for x in range(len(floats)):
        f = floats[x][i]
        if f > maxx:
            maxx = f
            maxi = x
    maxidx.append(maxi)

This extracts the lowest-numbered index in the cases where there is a tie.

(For brevity, this only uses 7 lists of length 7; but it should be obvious that the logic extends to any dimensions.)

Because Python’s variables are always references, you can actually build the outer array as a list of references to your existing variables if refactoring your current code seems like an excessive change.

floats = [List1, List2, List3, ...]

Array indices in Python are zero-based, so index 0 in the result means List1.

Answered By: tripleee

Put all of your lists into a single list. You can then manage the sublists in terms of "columns" using zip.

Like this:

List1 = [29.561801, 29.564141, 29.566480, 29.293966, 29.291252]
List2 = [26.602566, 22.752335, 22.755249, 22.754278, 22.756220]
List3 = [23.966560, 23.960471, 23.954381, 29.568819, 29.571159]

lists = [List1, List2, List3]

result = [c.index(max(c))+1 for c in zip(*lists)]

print(result)

Output:

[1, 1, 1, 3, 3]

Note:

Python list indexes are zero-based but it appears that the requirement is for 1-based indexing hence the addition

Answered By: SIGHUP