Hello! In our last lesson, we learned about loops, which allow us to repeat actions. We often used lists as the sequence of items to loop over, for example, for number in my_list:. Now, it's time to put lists themselves under the microscope.
This lesson is dedicated to understanding Python's most versatile and widely used data structure: the list. We will explore how to create lists, access individual items within them, extract subsections using a powerful technique called slicing, and modify them using a variety of built-in methods. Mastering lists is a crucial step in your Python journey, as they are fundamental to organizing and handling data in almost any program you will write.
What is a List?
At its core, a list is an ordered, mutable collection of items. Let's break that down:
- Ordered: The items in a list have a defined sequence, and that order will not change unless you explicitly change it. The first item you add stays the first item, the second stays the second, and so on.
- Mutable: This is a key characteristic. "Mutable" means you can change the list after it has been created. You can add new items, remove existing items, or change the items themselves.
- Collection of items: Lists are incredibly flexible and can hold items of any data type. You can have a list of numbers, a list of strings, or even a mixed list with numbers, strings, and booleans. You can also have lists inside other lists, creating nested structures.
You create a list by placing comma-separated items inside square brackets [].
# A list of strings
fruits = ["apple", "banana", "cherry"]
# A list of numbers
temperatures = [20.5, 22.1, 19.8]
# A mixed-type list
person_data = ["Alice", 30, True, 5.8]
# A list can be empty
empty_list = []
Python also offers some convenient shortcuts for creating and combining lists. Let's watch a short segment that demonstrates these techniques.
The video "How to Use Lists in Python" by Programming with Mosh provides a great introduction. Watch the first part, where he explains different ways to create lists.
Pay close attention to the section from the beginning, where he covers creating lists of repeating elements using the * operator, combining lists with the + operator, and creating a list from a range or a string.
Accessing and Modifying Elements: Indexing
Once you have a list, the most basic operation is to access its elements. Since lists are ordered, each element has a position, or index. In Python, indexing starts from zero.
my_list[0]gives you the first element.my_list[1]gives you the second element.- ...and so on.
Python also supports negative indexing, which is a handy way to access elements from the end of the list without needing to know its length.
my_list[-1]gives you the last element.my_list[-2]gives you the second-to-last element.
Since lists are mutable, you can use an element's index to change its value.
my_list = [10, 20, 30, 40]
# Access the first element
print(my_list[0]) # Output: 10
# Access the last element
print(my_list[-1]) # Output: 40
# Modify the second element
my_list[1] = 25
print(my_list) # Output: [10, 25, 30, 40]
For a detailed textual explanation of both positive and negative indexing, please read the following section from the article on k0nze.dev.
Python Course #8: Lists, List Slicing, and all List Functions (incl. Free Cheat Sheet) | k0nze
This article provides a thorough guide to Python lists. We'll start with the basics of accessing elements.
Please read the section Accessing Python List Elements. Focus on understanding the concept of zero-based indexing and how negative indices like -1 and -2 allow you to access elements from the end of the list.
Extracting Sub-Lists: Slicing
What if you need more than one element? You could access them one by one, but Python provides a much more powerful and elegant solution called slicing. Slicing lets you extract a portion of a list, creating a new, smaller list.
The syntax for slicing is list[start:stop:step].
start: The index of the first element you want to include (inclusive). If omitted, it defaults to the beginning of thelist (index 0).stop: The index of the element where the slice should end (exclusive). This is a crucial point: the element at thestopindex is not included in the result. If omitted, it defaults to the end of the list.step: An optional number indicating the interval between elements. If omitted, it defaults to 1 (taking every element).

Slicing is a rich topic with many uses. To get a comprehensive and visual understanding, let's watch a tutorial from Corey Schafer, who is excellent at explaining these concepts.
Python Tutorial: Slicing Lists and Strings
The video "Python Tutorial: Slicing Lists and Strings" by Corey Schafer is a focused guide on this exact topic. We will watch it in segments to absorb the concepts properly.
First, watch the section on the basic start and stop syntax. Pay close attention to why the stop index is non-inclusive. This is from basic slicing. Next, see what happens when you leave the start or stop index blank. This is a common and useful shortcut. Watch from omitting indices. Now, let's introduce the step parameter, which lets you skip elements. Watch the segment from the step parameter. Finally, see how a negative step can be used to reverse a list or parts of it. This is a very powerful technique. Watch from negative steps.
As you saw in the video, my_list[::-1] is a concise way to create a reversed copy of a list.
Common List Methods
Beyond indexing and slicing, lists come with a rich set of built-in functions, called methods, that allow you to manipulate them. A method is a function that "belongs" to an object and is called using dot notation, like my_list.append().
Here are some of the most essential list methods:
Adding Elements:
.append(item): Adds a single item to the very end of the list..insert(index, item): Inserts an item at a specific index, shifting everything else to the right..extend(another_list): Adds all the items fromanother_listto the end. This is similar to using the+operator.
Removing Elements:
.pop(index): Removes and returns the item at the given index. If no index is provided, it removes and returns the last item..remove(value): Searches for and removes the first occurrence of the specified value. If the value isn't found, it raises an error..clear(): Removes all items from the list, making it empty.
Organizing and Finding:
.sort(): Sorts the items of the list in place (ascending by default)..reverse(): Reverses the order of the elements in place..index(value): Returns the index of the first occurrence of the specified value..count(value): Returns the number of times a value appears in the list.
Copying a List:
.copy(): Returns a "shallow copy" of the list. This is extremely important. If you just writenew_list = old_list, you are not creating a new list; both variables point to the same list in memory. Modifying one will affect the other. Usingnew_list = old_list.copy()creates a truly independent new list.
For a complete reference, let's go back to the article from k0nze.dev.
Python Course #8: Lists, List Slicing, and all List Functions (incl. Free Cheat Sheet) | k0nze
This article provides an excellent summary of the most important list methods.
Please read the sections titled Changing List Elements, Manipulation Functions, and Property Functions. Don't worry about memorizing every single one right now; focus on understanding the purpose of append, insert, pop, remove, sort, index, and copy.
Let's Practice
Time to put it all together. Create a new Python file and follow the steps below to manipulate a list.
Problem:
You are given a list of tasks. Your goal is to perform a series of modifications to organize it.
Starting List:
Copy this list into your script:
tasks = ["wash dishes", "pay bills", "do laundry", "walk dog"]
Instructions:
- Change an item: Your "pay bills" task is actually to "pay electricity bill". Modify the second item in the list to reflect this. Print the updated list.
- Add to the end: You forgot a task. Add "buy groceries" to the end of the list. Print the updated list.
- Add to the beginning: The most urgent task is to "call mom". Insert this at the beginning of the list (index 0). Print the updated list.
- Remove by value: You've already walked the dog. Remove the "walk dog" task from the list. Print the updated list.
- Remove by index: You decide to do laundry later. Remove the item at index 2. Print the final list.
Try to solve this on your own before checking the solution.
Click to see the solution
tasks = ["wash dishes", "pay bills", "do laundry", "walk dog"]
print(f"Initial list: {tasks}")
# 1. Change an item
tasks[1] = "pay electricity bill"
print(f"After changing an item: {tasks}")
# 2. Add to the end
tasks.append("buy groceries")
print(f"After appending an item: {tasks}")
# 3. Add to the beginning
tasks.insert(0, "call mom")
print(f"After inserting an item: {tasks}")
# 4. Remove by value
tasks.remove("walk dog")
print(f"After removing by value: {tasks}")
# 5. Remove by index
# After the previous steps, 'do laundry' is now at index 2
# tasks = ['call mom', 'wash dishes', 'do laundry', 'pay electricity bill', 'buy groceries']
tasks.pop(2)
print(f"Final list: {tasks}")
Expected Final Output:
Final list: ['call mom', 'wash dishes', 'pay electricity bill', 'buy groceries']
Conclusion
Excellent work! You've just mastered the fundamentals of Python's most important data container. Lists are the workhorse you'll use constantly for storing, accessing, and organizing data.
Here are the key takeaways from today's lesson:
- Lists are ordered and mutable collections created with square brackets
[]. - Indexing (
my_list[i]) is used to access or modify single elements, with0for the first element and-1for the last. - Slicing (
my_list[start:stop:step]) is a powerful way to create sub-lists or even reversed copies of a list. Remember thestopindex is exclusive! - Methods like
.append(),.insert(),.pop(),.remove(), and.sort()provide the tools to dynamically manipulate your lists. - Always use
.copy()or slicing[:]to create a new, independent copy of a list to avoid accidentally modifying the original.
In our next lesson, we will explore two other crucial data structures: dictionaries and sets. While lists are perfect for ordered sequences, dictionaries excel at storing data as key-value pairs (like a real dictionary), and sets are ideal for managing collections of unique items.