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?
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
.
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
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?
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
.
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