# Finding the longest or shortest item in a list#

Python is a powerful language to quickly and efficiently do work with data, but it requires a more in-depth knowledge of the language to write more elegant and readable code. For many new Python programmers, this is a catch-22 as they’re still learning all the details and it takes time. Let’s take a simple example about finding the longest string in a list and simplify some code. Secondly making the code faster as we will use built-in functions at machine speed instead of interpreting Python code.

The example is a for-loop over a list and checks if the new item is longer than the current longest item before it stores it as the longest. Afterward, it prints the result which will be `longest` in this case.

``` 1#!/usr/bin/env python3
2
3def main():
4    mylist = ["find", "longest", "item", "in", "the", "list"]
5
6    word = ""
7    for item in mylist:
8        if len(item) > len(word):
9            word = item
10    print(word)
11
12
13if __name__ == "__main__":
14    main()
```

## Using builtin functions#

Python has built-in functions called `min()` and `max()` to find the smallest or biggest value in a list. In the example below the `max()` function is used to find the biggest numerical value and `min()` for the smallest numerical value.

``` 1#!/usr/bin/env python3
2
3def main():
4    mylist = [1, 2, 3, 5, 4]
5
6    max_value = max(mylist)
7    min_value = min(mylist)
8    print(min_value)
9    print(max_value)
10
11
12if __name__ == "__main__":
13    main()
```

As expected the output is `1` for the lowest value, and `5` as it is the highest value in the list.

```1
5
```

## Handling an empty sequence#

Using the built-in functions `min()` and `max()` will fail with `ValueError: max() arg is an empty sequence` if an empty sequence is used. Setting the default value to `0` will be returned when the sequence is empty. In the original example, we set the variable `word` to an empty string as the default value.

``` 1#!/usr/bin/env python3
2
3def main():
4    mylist = []
5
6    value = max(mylist, default=0)
7    print(value)
8
9
10if __name__ == "__main__":
11    main()
```

## Finding the longest item#

Now that we know about the `max()` function and how to handle empty sequences or a list in our example it is time to implement it. One key item still missing is that `max()` works with numerical values so we have to score all elements with a numerical value. The function `max()` has another option called `key` which can give a function to score the element and with function `len()` the length of a string element can be determined.

``` 1#!/usr/bin/env python3
2
3def main():
4    mylist = ["find", "longest", "item", "in", "the", "list"]
5
6    word = max(mylist, key=len, default="")
7    print(word)
8
9
10if __name__ == "__main__":
11    main()
```

Running example and prints the same result as in the original example we started with, but we reduced four-line into just one.

```longest
```

## Finding the shortest item#

By using the `min()` function we can find the shortest string in list and we didn’t had to rewrite selection code for it. Here we see a benefit already as we can just switch from `max()` to `min()` without any other modifications.

``` 1#!/usr/bin/env python3
2
3def main():
4    mylist = ["find", "longest", "item", "in", "the", "list"]
5
6    word = min(mylist, key=len, default="")
7    print(word)
8
9
10if __name__ == "__main__":
11    main()
```

## Changing the key calculation#

In the previous examples, the `len()` function was used to calculate the key value based on the length of the string. Other functions can also be used to calculate the key-value and in the example below we create a custom function for this. The calc function sums up the ASCII values for all characters in the string and returns that.

``` 1#!/usr/bin/env python3
2
3def calc(word: str) -> int:
4    return sum(list(map(ord, word)))
5
6
7def main():
8    mylist = ["aa", "ab", "ac", "ba"]
9
10    word = max(mylist, key=calc, default="")
11    print(word)
12
13
14if __name__ == "__main__":
15    main()
```

Note

The function `ord()` converts an ASCII character to an integer, and `map()` function iterates a function over a list.

A shorter way to write this is to use a lamba function and keep the function close to where it is used and making it more readable.

``` 1#!/usr/bin/env python3
2
3def main():
4    mylist = ["aa", "ab", "ac", "ba"]
5
6    word = max(mylist, key=(lambda value: sum(list(map(ord, value)))), default="")
7    print(word)
8
9
10if __name__ == "__main__":
11    main()
```

In both examples, the outcome is `ac` as it has the biggest numerical value if both ASCII values are summed up.

## Conclusion#

In the original example, we started with a custom piece of code to select an element from a list and replaced it with built-in functions. With this, the code length was reduced and the complexity as well. These built-in functions have been tested extensively with every Python release and have optimized execution in C instead of Python, reducing the chance of bugs and slow code.