
Exploring Other Features of Lists
Exploring Other Features of Lists êŽë š


Pythonâs list
has an impressive set of features, making it a versatile, flexible, and powerful data structure. So far, youâve learned about most of these features. Youâve learned to create lists, add and remove items from your lists, traverse existing lists in a loop or comprehension, and much more.
In the following sections, youâll learn about some additional features that make lists even more powerful. Youâll learn how to find items in a list, determine the minimum and maximum values, and get the listâs length. Youâll also explore the details of how Python compares lists to each other.
Finding Items in a List
Python has a few tools that allow you to search for values in an existing list. For example, if you only need to quickly determine whether a value is present in a list, but you donât need to grab the value, then you can use the in
or not in
operator, which will run a membership test on your list.
Note
To learn more about the in
and not in
operators and how to perform membership tests, check out Pythonâs âinâ and ânot inâ Operators: Check for Membership. These operators can be pretty useful when you need to check if a Python string contains a substring.
As its name suggests, a membership test is a Boolean test that allows you to find out whether an object is a member of a collection of values. The general syntax for membership tests on list objects looks something like this:
item in list_object
item not in list_object
The first expression allows you to determine if item
is in list_object
. It returns True
if it finds item
in list_object
or False
otherwise. The second expression works in the opposite way, allowing you to check if item
is not in list_object
. In this case, you get True
if item
doesnât appear in list_object
.
Hereâs how membership tests work in practice:
usernames = ["john", "jane", "bob", "david", "eve"]
"linda" in usernames
#
# False
"linda" not in usernames
#
# True
"bob" in usernames
#
# True
"bob" not in usernames
#
# False
In this example, you have a list of users and want to determine whether some specific users are registered in your system.
The first test uses in
to check whether the user linda
is registered. You get False
because that user isnât registered. The second test uses the not in
operator, which returns True
as a confirmation that linda
isnât one of your users.
The .index()
method is another tool that you can use to find a given value in an existing list. This method traverses a list looking for a specified value. If the value is in the list, then the method returns its index. Otherwise, it raises a ValueError
exception:
usernames = ["john", "jane", "bob", "david", "eve"]
usernames.index("eve")
#
# 4
usernames.index("linda")
#
# Traceback (most recent call last):
# ...
# ValueError: 'linda' is not in list
In the first call to .index()
, you get the index where you can find the user named "eve"
. You can use this index later in your code to access the actual object as needed. In the second call, because the user "linda"
isnât in the list, you get a ValueError
with an explanatory message.
Note that if your searchâs target value appears several times in the list, then .index()
will return the index of the first occurrence:
sample = [12, 11, 10, 50, 14, 12, 50]
sample.index(12)
#
# 0
sample.index(50)
#
# 3
The .index()
method returns as soon as it finds the input value in the underlying list. So, if the value occurs many times, then .index()
always returns the index of the first occurrence.
Lists provide yet another method that you can use for searching purposes. The method is called .count()
, and it allows you to check how many times a given value is present in a list:
sample = [12, 11, 10, 50, 14, 12, 50]
sample.count(12)
#
# 2
sample.count(11)
#
# 1
sample.count(100)
#
# 0
The .count()
method takes an item as an argument and returns the number of times the input item appears in the underlying list. If the item isnât in the list, then you get 0
.
Searching for a specific value in a Python list isnât a cheap operation. The time complexity of .index()
, .count()
, and membership tests on lists is O(n). Such linear complexity may be okay if you donât need to perform many lookups. However, it can negatively impact performance if you need to run many of these operations.
Getting the Length, Maximum, and Minimum of a List
While working with Python lists, youâll face the need to obtain descriptive information about a given list. For example, you may want to know the number of items in the list, which is known as the listâs length. You may also want to determine the greatest and lowest values in the list. In all these cases, Python has you covered.
To determine the length of a list, youâll use the built-in len()
function. In the following example, you use this function as an intermediate step to calculate the average grade of a student:
grades = [80, 97, 86, 100, 98, 82]
n = len(grades)
sum(grades) / n
#
# 90.5
Here, you calculate the average grade of a student. To do this, you use the sum()
function to get the total sum and len()
to get the number of evaluated subjects, which is the length of your grades
list.
Itâs important to note that because lists keep track of their length, calling len()
is pretty fast, with a time complexity of O(1). So, in most cases, you donât need to store the return value of len()
in an intermediate variable as you did in the example above.
Note
To learn more about using the len()
function, check out Using the len()
Function in Python.
Another frequent task that youâll perform on lists, especially on lists of numeric values, is to find the minimum and maximum values. To do this, you can take advantage of the built-in min()
and max()
functions:
min([3, 5, 9, 1, -5])
#
# -5
max([3, 5, 9, 1, -5])
#
# 9
In these examples, you call min()
and max()
with a list of integer numbers. The call to min()
returns the smallest number in the input list, -5
. In contrast, the call to max()
returns the largest number in the list, or 9
.
Note
For a deeper dive into using the built-in min()
and max()
functions, check out Pythonâs min()
and max()
: Find Smallest and Largest Values.
Overall, Python lists support the len()
, min()
, and max()
functions. With len()
, you get the length of a list. With min()
and max()
, you get the smallest and largest values in a list. All these values can be fairly useful when youâre working with lists in your code.
Comparing Lists
You can also face the need to compare lists. Fortunately, list objects support the standard comparison operators. All these operators work by making item-by-item comparisons within the two involved lists:
[2, 3] == [2, 3]
#
# True
[5, 6] != [5, 6]
#
# False
[5, 6, 7] < [7, 5, 6]
#
# True
[5, 6, 7] > [7, 5, 6]
#
# False
[4, 3, 2] <= [4, 3, 2]
#
# True
[4, 3, 2] >= [4, 3, 2]
#
# True
When you compare two lists, Python uses lexicographical ordering. It compares the first two items from each list. If theyâre different, this difference determines the comparison result. If theyâre equal, then Python compares the next two items, and so on, until either list is exhausted.
In these examples, you compare lists of numbers using the standard comparison operators. In the first expression above, Python compares 2
and 2
, which are equal. Then it compares 3
and 3
to conclude that both lists are equal.
In the second expression, Python compares 5
and 5
. Theyâre equal, so Python has to compare 6
and 6
. Theyâre equal too, so the final result is False
.
In the rest of the expressions, Python follows the same pattern to figure out the comparison. In short, Python compares lists in an item-by-item manner using lexicographical comparison. The first difference determines the result.
You can also compare lists of different lengths:
[5, 6, 7] < [8]
#
# True
[5, 6, 7] == [5]
#
# False
In the first expression, you get True
as a result because 5
is less than 8
. That fact is sufficient for Python to solve the evaluation. In the second example, you get False
. This result makes sense because the lists donât have the same length, so they canât be equal.
As you can see, comparing lists can be tricky. Itâs also an expensive operation that, in the worst case, requires traversing two entire lists. Things get more complex and expensive when you compare lists of strings. In this situation, Python will also have to compare the strings character by character, which adds cost to the operation.