Python Arena
Step 5 of 5

The best item so far

max and min know only one kind of best: the greatest or the smallest value. Often you want another kind: the longest word, the day with the most rain, the number closest to a target. Then you write the search yourself. The trick is one variable, set before the loop, that holds the best item so far. Every item is compared with it, and the winner of each comparison stays:

def longest(words: list) -> str:
    best = words[0]
    for word in words:
        if len(word) > len(best):
            best = word
    return best


print(longest(["fig", "banana", "kiwi", "cherry"]))
Output
banana

best starts as the first word, so there's always a real word to compare with. In each round, a word that is longer than best takes its place. When the loop ends, every word has had its turn, so best is the longest of all. cherry is as long as banana, but not longer, so the first of the two stays.

Where to start

Start the helper variable from an item of the list, not from a number you made up. A start of 0 looks harmless, but it breaks whenever no item can beat it: for the warmest, a list where every item is below 0; for the coldest, a list where every item is above 0:

def coldest(temperatures: list) -> int:
    best = 0
    for t in temperatures:
        if t < best:
            best = t
    return best


def warmest(temperatures: list) -> int:
    best = 0
    for t in temperatures:
        if t > best:
            best = t
    return best


winter = [-8, -3, -12, -5]
summer = [21, 18, 25]
print(coldest(winter))
print(warmest(winter))
print(coldest(summer))
Output
-12
0
0

The warmest winter temperature isn't 0: it's -3. The coldest summer temperature isn't 0 either: it's 18. In both wrong answers no temperature beat the start value 0, so 0 was returned, though it isn't even in the list. With best = temperatures[0], both functions are right for any list.

Remembering where the best item is

To know where the best item is, and not only what it is, remember its index. Go through the indexes, and keep the index of the best item so far:

def rainiest_day(rain: list) -> int:
    best = 0
    for i in range(len(rain)):
        if rain[i] > rain[best]:
            best = i
    return best + 1


week = [2, 0, 14, 5, 14, 1, 0]
print("Most rain on day", rainiest_day(week))
Output
Most rain on day 3

Here best is an index, so starting it from 0 is right: it means the first day. The function returns best + 1 because people count days from 1.

Your task

Challenge 1 of 3

Fill in the blanks so that first_in_dictionary(words) returns the word that comes first in alphabetical order when capital letters don't matter, as in a dictionary. (min won't do here: it puts every word that starts with a capital letter before the words in small letters.) For example, first_in_dictionary(["melon", "Cherry", "apple"]) returns 'apple'.

Challenge 2

Write the function coldest_day(temperatures: list) -> int, which returns the number of the day with the lowest temperature. Days are numbered from 1. If several days are equally cold, return the first of them. For example, coldest_day([5, -2, 3, -2]) returns 2.

Challenge 3

Write the function closest_to(numbers: list, target: int) -> int, which returns the number in the list that is closest to target. If two numbers are equally close, return the one that comes first. For example, closest_to([10, 25, 18, 40], 20) returns 18.

Python's function abs helps here: it returns a number without its minus sign, so abs(18 - 20) and abs(22 - 20) are both 2, the distance from 20.