I am in a Python beginners class. We are not allowed to import any modules, nor use max(), min(), sort(ed)(). I have already defined my own min()max(). But for simplicity here I will use max()min(). I have a 2D array, and I am trying to find a way to reference the first line of the array, to a value in the array. Allow me to elaborate.
First row is years. First column is countries. Data in the array is population. I wrote a statement to find the max population for a country...now how do I write a statement to find which year that max population was in? Then I need to print everything out in a table, where I will have country, max population, year it happened in.
Code so far:
list = [['countries', 2019, 2020, 2025],['aruba', 2349834,23432098,8798734],['barbados', 445673,980897,342431],['japan', 12131441,7897879,3636436]]
for row in list[1:]:
for colum in row:
maxPop = max(row[1:])
minPop = min(row[1:])
chgPop = float(f'{(((row[3] - row[1]) / row[1]) * 100):.2f}')
print(f'{row[0]:<10}{minPop:25}{maxPop:>20}{chgPop:>15.1f}')
This code goes to the second row, and the second column, to start working on the data for maxPop minPop and chgPop. But say now I have found a maxPop for barbados, which I can print out nicely.... how do I add another column in that print out where I print the year in which that maxPop happend?
I surmise that I would loop through the list again, and use an index reference where that maxPop happened in the list, and use the column in that index reference to pick out the year from the first row. This loop would go through the entire list, and a new variable called maxPopYear could then be added to my print statement. But how do i go about that?
The expected output would look like this
country minpop year maxpop year pop%
aruba 1232198 2020 939439 2019 5.43
barbados 56356 2022 4544 2019 34.33
etc
CodePudding user response:
Since you need to define your max()
function you can easily have it return the index of the greatest value, or even better a tuple
containing both the index and the value. So when you find the maximum you also know where it is in your data. The same goes for the custom min()
of course. For instance you may do:
def mymax(it):
maxval = -1
for i,v in enumerate(it):
if v > maxval:
maxval = v
maxidx = i
return (maxidx, maxval)
mymax([445673,980897,342431])
(1, 980897)
CodePudding user response:
So you can use the built in function for list in python called index
.
data = [
["countries", 2019, 2020, 2025],
["aruba", 2349834, 23432098, 8798734],
["barbados", 445673, 980897, 342431],
["japan", 12131441, 7897879, 3636436],
]
for row in data[1:]:
for column in row:
maxPop = max(row[1:])
minPop = min(row[1:])
chgPop = float(f"{(((row[3] - row[1]) / row[1]) * 100):.2f}")
year = data[0][row.index(maxPop)]
print(f"{row[0]:<10}{minPop:25}{maxPop:>20}{chgPop:>15.1f}{year:>20}")
This outputs:
aruba 2349834 23432098 274.4 2020
barbados 342431 980897 -23.2 2020
japan 3636436 12131441 -70.0 2019
the easy implementation of the index
function is
def index(a:list, value) -> int:
for i, item in enumerate(a):
if item == value:
return i
raise ValueError(f"{value} not in list")
To use it just replace the line with year = data[0][index(row, maxPop)]
Or even better, just like @gimix suggested, return the index along as a tuple with your max or min function. You can have a function called argmin
and argmax
which returns only the index of the min and max values respectively and use that to get the value.
def argmax(it:list) -> int:
maxval = -1
maxidx = None
for i, v in enumerate(it):
if v > maxval:
maxval = v
maxidx = i
return maxidx