Guide to Lists in Python

Guide to Lists in Python

Introduction

Python, as one of the most versatile and widely-used programming languages, boasts a plethora of built-in data structures that make it an excellent choice for developers of all skill levels. One such data structure is the list. It is one of the most powerful and flexible data structures in Python.

In this comprehensive guide, we will dive deep into the world of Python lists, exploring their many uses and applications in a variety of programming scenarios. We'll provide you with a solid understanding of Python lists, from their basic structure and usage to more advanced techniques and best practices.

Basics of Python Lists

A list in Python is a mutable, ordered collection of elements. The elements can be of various data types such as integers, floats, strings, or even other data structures like dictionaries and sets. The flexibility and dynamic nature of lists make them an invaluable asset when working with data in Python.

Note: To fully understand lists in Python you need to make sure you understand what mutable, ordered collection actually means. The fact that lists in Python are mutable means that a list in Python can be modified or changed after its creation. Elements can be added, removed, or updated within the list. On the other hand, elements of the ordered collection are stored in a specific order, and each element has a unique index or position within the list. This order is maintained, allowing you to access, insert, or remove elements based on their positions in the list.

How to Create a List in Python

The most common way to create a list in Python is to simply enclose a comma-separated sequence of elements within square brackets:

numbers = [1, 2, 3, 4, 5]
cars = ['chevrolet', 'ford', 'gmc']
mixed_data = [2, 'hello', 3.14, True]

Another practical way you can create a list is to use the list() constructor to create a list. This is particularly useful when converting other iterable objects, such as strings or tuples, into lists:

empty_list = list()
# []
string_to_list = list('hello')
# ['h', 'e', 'l', 'l', 'o']
tuple_to_list = list((1, 2, 3))
# [1, 2, 3]

How to Access Elements of a Python List

You can access individual elements of a list by their index, which starts from zero:

cars = ['chevrolet', 'ford', 'gmc']
print(cars[0])  # Output: chevrolet
print(cars[1])  # Output: ford

Python also allows you to use negative indexing, which starts from the end of the list:

cars = ['chevrolet', 'ford', 'gmc']
print(cars[-1])  # Output: gmc
print(cars[-2])  # Output: ford

Note: Using negative indexing is helpful when you want to access elements from the end without calculating the length of the list!

You can extract a portion of the list, also known as a sublist or slice, by specifying the start and end indices separated by a colon. If the start or end index is omitted, it defaults to the beginning or end of the list, respectively:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
first_five = numbers[:5]      # Output: [0, 1, 2, 3, 4]
last_five = numbers[-5:]      # Output: [5, 6, 7, 8, 9]
middle = numbers[3:7]         # Output: [3, 4, 5, 6]

With these basic concepts in mind, you're now ready to start working with lists in Python. In the next section, we'll explore various operations that can be performed on lists to manipulate and manage data.

Operations you can Perform on Lists in Python

How to Add Elements to a List

The append() method allows you to add a single element to the end of the list:

cars = ['chevrolet', 'ford', 'gmc']
cars.append('cadillac')
print(cars)  # Output: ['chevrolet', 'ford', 'gmc', 'cadillac']

The insert() method enables you to insert an element at a specific index in the list, shifting existing elements to the right:

cars = ['chevrolet', 'ford', 'gmc']
cars.insert(1, 'cadillac')
print(cars)  # Output: ['chevrolet', 'cadillac', 'ford', 'gmc']

The extend() method is used to append multiple elements to a list. It takes an iterable, such as another list, tuple, or string, as its_ argument and adds its elements to the end of the original list:

cars = ['chevrolet', 'ford', 'gmc']
cars.extend(['cadillac', 'buick'])
print(cars)  # Output: ['chevrolet', 'ford', 'gmc', 'cadillac', 'buick']

Advice: If you need to have a more comprehensive understanding of the differences between those three approaches to adding elements to a list in Python, consider taking a look at our "append() vs extend() vs insert() in Python Lists" article.

How to Remove Elements From a List

The remove() method is used to remove the first occurrence of a specified element from the list:

cars = ['chevrolet', 'ford', 'gmc']
cars.remove('ford')
print(cars)  # Output: ['chevrolet', 'gmc']

The pop() method removes and returns the element at a specified index:

cars = ['chevrolet', 'ford', 'gmc']
cars.pop(1)
print(cars)  # Output: ['chevrolet', 'gmc']

Note: If no index is provided, the pop() method removes and returns the last element:

cars.pop()
print(cars)  # Output: ['chevrolet']

The del keyword is used to remove an element or slice of elements from a list by its index:

cars = ['chevrolet', 'ford', 'gmc']
del cars[1]
print(cars)  # Output: ['chevrolet', 'gmc']

del cars[0:2]
print(cars)  # Output: []

The clear()method is used to remove all elements from a list, effectively emptying it:

cars = ['chevrolet', 'ford', 'gmc']
cars.clear()
print(cars)  # Output: []

Advice: You can read a more in-depth overview of the mentioned methods in the "Remove Element from an Array/List in Python" article.

How to Update List Elements

You can update individual elements of a list by accessing them by their index and assigning a new value:

cars = ['chevrolet', 'ford', 'gmc']
cars[1] = 'cadillac'
print(cars)  # Output: ['chevrolet', 'cadillac', 'gmc']

How to Concatenate Two Lists

You can concatenate two or more lists using the + operator:

cars = ['chevrolet', 'ford', 'gmc']
more_cars = ['cadillac', 'buick']
all_cars = cars + more_cars
print(all_cars)  # Output: ['chevrolet', 'ford', 'gmc', 'cadillac', 'buick']

Advice: For more information about concatenating two lists in Python, read our "How to Concatenate Two Lists in Python" article.

How to Make Multiple Lists Out of One

You can create a new list that contains multiple copies of an existing list by using the * operator.

cars = ['chevrolet', 'ford', 'gmc']
lots_of_cars = cars * 3
print(lots_of_cars) 
# Output: ['chevrolet', 'ford', 'gmc', 'chevrolet', 'ford', 'gmc', 'chevrolet', 'ford', 'gmc']

Common List Methods in Python

In addition to the basic list operations we covered in the previous section, Python provides several built-in methods for performing common tasks on lists, such as counting the number of list elements, sorting lists, and so on. Let's take a look at each of them, one by one.

The index() Method

The index() method is a built-in function in Python that is used to find the index of the first occurrence of an element in a list. It takes one argument, which is the value you want to find in the list, and returns the index of the first occurrence of that value.

Let's take a look at the syntax for using the index() method:

list_name.index(value, start, end)

Where:

  • list_name is the name of the list you want to search
  • value is the value you want to find in the list
  • start is the optional index from which to start the search (defaults to 0)
  • end is the optional index at which to end the search (defaults to the end of the list)

Note: If the specified value is not found in the list, the index() method will raise a ValueError exception.

Let's see how we can use the index() method for finding elements in the altered cars list, similar to what we used in the previous sections:

cars = ['chevrolet', 'ford', 'gmc', 'ford']
print(cars.index('ford'))  # Output: 1
print(cars.index('ford', 2))  # Output: 3

In this example, we have a list of fruits and we use the index() method to find the index of the first occurrence of the value 'ford'. The first call to index() returns 1, which is the index of the first occurrence of 'ford' in the list. The second call to index() specifies a start index of 2, so it starts searching for 'ford' from the third element of the list and returns 3, which is the index of the second occurrence of 'ford'.

Advice: You can find a more comprehensive overview of the index() method in our "Python: Check Index of an Item in a List" article.

The count() Method

The count() method is a built-in function in Python that is used to count the number of occurrences of a specific element in a list. It takes one argument, which is the value you want to count in the list, and returns the number of times that value appears in the list. Take a quick look at the syntax of the count() method:

list_name.count(value)

Here, the list_name is the name of the list you want to search and the value is the value you want to count in the list.

Now, we can take a look at a simple example of how to use the count() method:

cars = ['chevrolet', 'ford', 'gmc', 'ford']
print(cars.count('ford'))  # Output: 2

In this example, we have a list of cars and we use the count() method to count the number of times the value 'ford' appears in the list. The method returns 2, which is the number of times 'ford' appears in the list.

Note: The count() method is case-sensitive, so it will count only the occurrences of the exact value you pass to it. If you have a list of mixed case strings and you want to count all the occurrences of a particular string regardless of case, you can first convert all the strings to lowercase (or uppercase) using a list comprehension and then call the count() method on the resulting list:

cars = ['chevrolet', 'FORD', 'gmc', 'ford']
print([c.lower() for c in cars].count('ford'))  # Output: 2

In this example, we first use list comprehension (more on that later in this article) to create a new list where all the strings are in lowercase, and then we call the count() method on the new list to count the number of times the string 'banana' appears (in any case).

The reverse() Method

The reverse() method is a built-in function in Python that is used to reverse the order of elements in a list. It does not take any arguments and modifies the original list in place. Here's an example of how to use the reverse() method:

cars = ['chevrolet', 'ford', 'gmc']
cars.reverse()
print(cars)  # Output: ['gmc', 'ford', 'chevrolet']

Here, we, again, have a list of cars and we use the reverse() method to reverse the order of the elements in the list. The method modifies the original list in place and we print the modified list, which now has the elements in reverse order.

Note that the reverse() method does not return a new list - it modifies the original list in place. If you want to create a new list with the elements in reverse order, you can use slicing with a step of -1.

The sort() Method

The sort() method in Python sorts the elements of a list in ascending order by default. You can also modify the sorting behavior by using optional parameters like key and reverse. The method sorts the list in-place, meaning it modifies the original list and does not create a new sorted list.

First, let's take a look at the syntax of the sort() method in Python:

list.sort(key=None, reverse=False)

Here, the key is an optional argument that is a function that serves as a custom comparison key. The function is applied to each element in the list before sorting, and the resulting values are used to determine the order. The reverse is also an optional argument that takes a boolean value that, if set to True, sorts the list in descending order.

Now, we can take a look at examples of using the sort() method to sort lists in Python:

# Sorting a list of numbers in ascending order (default behavior)
numbers = [4, 2, 9, 1, 7]
numbers.sort()
print(numbers)  # Output: [1, 2, 4, 7, 9]

# Sorting a list of strings in descending order
cars = ['chevrolet', 'ford', 'gmc']
cars.sort(reverse=True)
print(cars)  # Output: ['gmc', 'ford', 'chevrolet']

# Sorting a list of tuples by the second element
tuples = [(1, 'one'), (3, 'three'), (2, 'two'), (4, 'four')]
tuples.sort(key=lambda x: x[1])
print(tuples)  # Output: [(1, 'one'), (4, 'four'), (3, 'three'), (2, 'two')]

Note: Keep in mind that the sort() method only works with lists. If you want to sort other iterable objects like tuples or sets, you can use the sorted() function which returns a new sorted list without modifying the original iterable.

The copy() Method

In Python, the copy() method is used to create a shallow copy of a list. A shallow copy refers to the process of creating a new collection object (such as a list, dictionary, or set) that is a copy of the original object, with a new reference, but with the same elements as the original object:

# Create the original list
cars = ['chevrolet', 'ford', 'gmc']

# Create the shallow copy
new_cars = cars.copy()

# Check if the two lists are different objects in memory
print(cars is new_cars)        # Output: False

# Verify the copy has been made
print(cars)       # Output: ['chevrolet', 'ford', 'gmc']
print(new_cars)   # Output: ['chevrolet', 'ford', 'gmc']

# Change the last element of the original list
cars[2] = 'cadillac'

# The change is not propagated to the copied list
print(cars)       # Output: ['chevrolet', 'ford', 'cadillac']
print(new_cars)   # Output: ['chevrolet', 'ford', 'gmc']

However, the elements themselves are not deep-copied, so if the original object contains nested structures (like lists or dictionaries), the references to these nested objects are copied, not the objects themselves. This means that changes made to the nested objects in the original object will also be reflected in the shallow copy and vice versa:`

# Create the original list
cars = ['chevrolet', 'ford', ['gmc', 'chevrolet']]

# Create the shallow copy
new_cars = cars.copy()

# Check if the two lists are different objects in memory
print(cars is new_cars)        # Output: False

# Verify the copy has been made
print(cars)       # Output: ['chevrolet', 'ford', ['gmc', 'chevrolet']]
print(new_cars)   # Output: ['chevrolet', 'ford', ['gmc', 'chevrolet']]

# Change the last element of the original list
cars[2][1] = 'cadillac'

# The change to the nested element is propagated to the copied list
print(cars)       # Output: ['chevrolet', 'ford', ['gmc', 'cadillac']]
print(new_cars)   # Output: ['chevrolet', 'ford', ['gmc', 'cadillac']]

Note: The copy() method creates a shallow copy, so if the list contains mutable objects like other lists, the inner lists will still refer to the same objects in memory. If you need to create a deep copy of the list, where even the inner mutable objects are duplicated, you can use the copy module's deepcopy() function.

Advice: If you want to know more about the differences between copy() and deepcopy() in Python, you should read our "Python: Deep and Shallow Copy Object" article.

List Functions in Python

In addition to the built-in list methods, Python also provides several list functions that can be used to perform various operations on lists.

The len() Function

You can use the len() function to determine the length of a Python list, which is the number of elements it contains. When you pass a list as an argument to the len() function, it returns an integer representing the number of elements in the list:

my_list = [10, 20, 30, 40, 50]
length = len(my_list)
print(length)  # Output: 5

The my_list contains 5 elements, so the len() function returns 5.

It's important to note that the len() function takes the list's structure into account. For example, say you have a nested list (a list within a list), the len() function only counts the outer list elements, not the individual elements within the nested list:

Free eBook: Git Essentials

Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!

nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
length = len(nested_list)
print(length)  # Output: 3

Here, the nested_list contains 3 elements (each of which is a list), so the len() function returns 3.

min() and max() Functions

The min() and max() functions are built-in Python functions used to find the minimum and maximum values, respectively, from a given iterable, such as a list. These functions return the smallest and largest values from the iterable based on their natural order (i.e., numeric or alphabetical order).

Let's take a look at a simple example of using the min() and max() functions with a Python list of integers:

my_list = [10, 20, 30, 40, 50]

minimum_value = min(my_list)
print(minimum_value)  # Output: 10

maximum_value = max(my_list)
print(maximum_value)  # Output: 50

The my_list contains integers, and the min() and max() functions return the smallest and largest values, respectively.

Advice: To learn more about the usage of the min() and max() functions on Python lists, read the "How to Get the Max Element of a Python List" section of our "Python: Get Max Element of List, Dictionary, or Tuple" article.

You can also use the min() and max() functions with lists of strings. In this case, the functions return the smallest and largest values based on alphabetical order:

my_list = ['apple', 'banana', 'cherry', 'orange', 'grape']

minimum_value = min(my_list)
print(minimum_value)  # Output: 'apple'

maximum_value = max(my_list)
print(maximum_value)  # Output: 'orange'

Note: When using the min() and max() functions with mixed data types, a TypeError will be raised, as Python cannot compare different data types directly.

The sum() Function

The sum() function returns the sum of all elements in a list, assuming that the elements are numeric. The sum() function takes the iterable as its first argument and an optional second argument, which is the starting value for the sum (default is 0):

my_list = [10, 20, 30, 40, 50]
total = sum(my_list)
print(total)  # Output: 150

In this example, the sum() function calculates the total of all the integers in my_list and returns the value 150.

You can also use the sum() function with an optional second argument to specify the starting value for the sum:

my_list = [10, 20, 30, 40, 50]
starting_value = 100
total = sum(my_list, starting_value)
print(total)  # Output: 250

In this case, the sum starts at 100 and then adds the elements of my_list, resulting in a total of 250.

Note: The sum() function expects an iterable containing numeric values. If the iterable contains non-numeric values, such as strings or other data types, a TypeError will be raised.

any() and all() Functions

The any() and all() functions are Python built-in functions used to test whether any or all elements in a list (or any other iterable) meet a certain condition.

Note: Both any() and all() work with iterables containing boolean values or elements that can be evaluated as truthy or falsy.

any() returns True if at least one element in the iterable is truthy (i.e., evaluates to True), and False otherwise:

my_list1 = [True, False, True, False]
my_list2 = [True, True, True]
my_list3 = [False, False, False]

result1 = any(my_list1)
print(result1)  # Output: True

result2 = any(my_list2)
print(result2)  # Output: True

result3 = any(my_list3)
print(result3)  # Output: False

all() returns True if all elements in the iterable are truthy (i.e., evaluate to True), and False otherwise:

my_list1 = [True, False, True, False]
my_list2 = [True, True, True]
my_list3 = [False, False, False]

result1 = all(my_list1)
print(result1)  # Output: False

result2 = all(my_list2)
print(result2)  # Output: True

result3 = all(my_list3)
print(result3)  # Output: False

You can also use the any() and all() functions with list comprehension to check for a specific condition on the elements of a list. For example, you can check if any or all elements in a list of integers are even:

numbers = [2, 4, 6, 8, 10]

any_even = any(num % 2 == 0 for num in numbers)
print(any_even)  # Output: True

all_even = all(num % 2 == 0 for num in numbers)
print(all_even)  # Output: True

Since all elements in the numbers list are even, both any() and all() return True.

Advice: To see more use cases and examples of the any() and all() functions in Python, read our "any() and all() in Python with Examples" article.

The sorted() Function

The sorted() function sorts the elements of a list in ascending or descending order. By default, the function returns a new list containing the sorted elements, without modifying the original iterable:

cars = ['chevrolet', 'ford', 'gmc', 'cadillac']
sorted_cars = sorted(cars)
print(sorted_cars)  # Output: ['cadillac', 'chevrolet', 'ford', 'gmc']

In this example, the sorted() function returns a new list containing the sorted elements of my_list in ascending order.

Note: The sorted() function works with different types of iterables, such as tuples and strings, and always returns a sorted list.

You can also use the sorted() function with an optional key argument to specify a custom sorting order based on a function:

cars = ['chevrolet', 'ford', 'gmc', 'cadillac']
sorted_cars = sorted(cars, key=len)
print(sorted_cars)  # Output: ['gmc', 'ford', 'cadillac', 'chevrolet']

In this case, the sorted() function sorts the elements of my_list based on their string length.

Additionally, the sorted() function accepts an optional reverse argument, which can be set to True to sort the elements in descending order:

cars = ['chevrolet', 'ford', 'gmc', 'cadillac']
sorted_cars = sorted(cars, reverse=True)
print(sorted_cars)  # Output: ['gmc', 'ford', 'chevrolet', 'cadillac']

This results in creating a new list containing the sorted elements of my_list in descending order.

Advanced List Techniques in Python

List Comprehension

List comprehension is a concise and elegant way to create a new list from an existing list or other iterable object. It is particularly useful when you want to apply a transformation or filter to the elements of a list.

Take a look at how easy it is to create a new list from an existing list by squaring each element:

numbers = [1, 2, 3, 4, 5]
# Create a new list using list comprehension
squares = [num**2 for num in numbers]
print(squares)  # Output: [1, 4, 9, 16, 25]

You can also use conditional statements in list comprehension to filter out elements that do not meet a certain condition:

numbers = [1, 2, 3, 4, 5]
# Create a new list from an existing list by selecting only the even numbers
evens = [num for num in numbers if num % 2 == 0]
print(evens)  # Output: [2, 4]

Advice: List comprehension can be a powerful technique for working with lists in Python, especially when dealing with large datasets. For a more comprehensive overview of list comprehension in Python, read our "List Comprehensions in Python" article.

Lambda Functions with Lists

Lambda functions are anonymous functions that can be used as a quick way to perform simple operations on lists. They are particularly useful when used in combination with list methods such as map(), filter(), and reduce():

numbers = [1, 2, 3, 4, 5]
squared_numbers = map(lambda x: x**2, numbers)
print(list(squared_numbers))  # Output: [1, 4, 9, 16, 25]

You can also use lambda functions to filter out elements that do not meet a certain condition using the filter() method:

numbers = [1, 2, 3, 4, 5]
# Use a lambda function to select only the even numbers in a list
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers))  # Output: [2, 4]

Advice: To dive deeper into the field of Python lambda functions, read our "Lambda Functions in Python" article.

List Slicing and Striding

List slicing and striding are advanced techniques that allow you to extract specific subsets of elements from a list. Let's take a look at how to slice a list to extract a portion of the elements:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
subset = numbers[2:7]
print(subset)  # Output: [2, 3, 4, 5, 6]

You can also use negative indices to slice a list from the end:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
subset = numbers[-5:-2]
print(subset)  # Output: [5, 6, 7]

List striding is a technique that allows you to extract every nth element from a list. You can specify the stride value by adding a third index to the slice notation. Take a look at how to extract every second element from a list:

numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
subset = numbers[1::2]
print(subset) # Output: [1, 3, 5, 7, 9]

Advice: You can find more interesting info in the "Python: Slice Notation on List" article.

Enumerate Function

The enumerate() function is a built-in Python function that allows you to iterate through a list (or other iterable) while keeping track of the current index. It returns an iterator that yields pairs of the form (index, element) for each element in the list

cars = ['chevrolet', 'ford', 'gmc']
for index, car in enumerate(cars):
    print(index, car)

This will give us:

0 chevrolet
1 ford
2 gmc

Advice: If you'd like to read more about the enumerate() function in Python, read our "Guide to enumerate() in Python - Easy for Loops with Counting".

Zip Function

The zip() function is a built-in Python function that takes two or more lists (or other iterables) as arguments and returns an iterator that yields tuples containing the corresponding elements from each input list. It can be used to combine elements from multiple lists in a pairwise manner. For example:

names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
for name, age in zip(names, ages):
    print(name, age)

Advice: Dive deeper into the field of the zip() function in Python by reading our "The Python zip() Function" article.

Unpacking Lists

Unpacking in Python refers to an operation that consists of assigning an iterable's items into different variables:

numbers = [1, 2, 3]
a, b, c = numbers
print(a)  # Outputs: 1
print(b)  # Outputs: 2
print(c)  # Outputs: 3

The values in the list numbers are unpacked into the variables a, b, and c respectively.

If you have a list of unknown length and you want to unpack some elements into individual variables and the rest into another list, you can use the * operator:

numbers = [1, 2, 3, 4, 5, 6]
a, b, *rest = numbers
print(a)  # Outputs: 1
print(b)  # Outputs: 2
print(rest)  # Outputs: [3, 4, 5, 6]

In this case, a and b will take the first and second elements respectively, and rest will be a new list containing any remaining elements.

You can also use the * operator to grab elements from the middle of a list:

numbers = [1, 2, 3, 4, 5, 6]
a, *middle, z = numbers
print(a)  # Outputs: 1
print(middle)  # Outputs: [2, 3, 4, 5]
print(z)  # Outputs: 6

a will be the first element, z will be the last element, and middle will be a new list containing the elements between a and z.

Note: The * operator can only be used once in a list unpacking operation. If you use it more than once, Python won't know how to distribute the elements.

Conclusion

Python provides a variety of built-in methods and functions for working with lists, including adding and removing elements, updating elements, sorting, and more. Advanced techniques such as list comprehension, lambda functions, slicing, and striding allow you to perform more complex operations on lists efficiently. Lists are a powerful tool in Python and are essential for many programming applications, making it essential to master their use.

Last Updated: May 12th, 2023
Was this article helpful?

Improve your dev skills!

Get tutorials, guides, and dev jobs in your inbox.

No spam ever. Unsubscribe at any time. Read our Privacy Policy.

© 2013-2023 Stack Abuse. All rights reserved.

AboutDisclosurePrivacyTerms