Lists
Learn how to create, modify, and organize collections of data using Python lists, including common list methods and copying pitfalls.
Introduction
Real programs rarely deal with just one piece of data — you need to store a shopping list, a set of student scores, or a collection of usernames. Python's list is the go-to data structure for storing an ordered collection of items.
This lesson covers how to create lists, access their contents, change them after creation, and use the most important built-in list methods.
- How to create lists and access items with indexing and slicing.
- Why lists are mutable, unlike strings.
- The most common list methods: append, insert, remove, pop, sort, reverse, and extend.
- How to store mixed data types in one list.
- How to copy a list correctly and avoid the aliasing pitfall.
- A brief look at nested lists.
What is a List?
A list is an ordered, changeable collection of items, written using square brackets with items separated by commas. Lists can hold any type of data, and items keep the order in which they were added.
fruits = ["apple", "banana", "cherry"]
print(fruits)
print(type(fruits))
print(len(fruits))['apple', 'banana', 'cherry']
<class 'list'>
3Creating Lists
You can create a list by writing items directly inside square brackets, or by creating an empty list and adding items later.
numbers = [10, 20, 30, 40]
empty_list = []
single_item = ["only one"]
print(numbers)
print(empty_list)
print(single_item)[10, 20, 30, 40]
[]
['only one']Indexing and Slicing
Lists support the same indexing and slicing rules you learned for strings — zero-based positive indices, negative indices from the end, and slice syntax with start:stop:step.
fruits = ["apple", "banana", "cherry", "date", "fig"]
print(fruits[0])
print(fruits[-1])
print(fruits[1:4])
print(fruits[::-1])apple
fig
['banana', 'cherry', 'date']
['fig', 'date', 'cherry', 'banana', 'apple']Lists Are Mutable
Unlike strings, lists are mutable — you can change, add, or remove items after the list is created, without creating a whole new object.
fruits = ["apple", "banana", "cherry"]
fruits[1] = "blueberry"
print(fruits)['apple', 'blueberry', 'cherry']Strings create a new object every time you "change" them. Lists are changed in place — the same list object is modified directly. This distinction becomes very important once you learn about copying lists later in this lesson.
Common List Methods
Python lists come with built-in methods for adding, removing, and reorganizing items.
append(item)
Adds a single item to the end of the list.
insert(index, item)
Inserts an item at a specific position.
remove(item)
Removes the first matching item by value.
pop(index)
Removes and returns the item at a position (last item by default).
sort()
Sorts the list in place, in ascending order by default.
reverse()
Reverses the order of items in place.
extend(iterable)
Adds all items from another list (or iterable) to the end.
numbers = [5, 2, 9]
numbers.append(1)
print(numbers)
numbers.insert(1, 100)
print(numbers)[5, 2, 9, 1]
[5, 100, 2, 9, 1]numbers = [5, 100, 2, 9, 1]
numbers.remove(100)
print(numbers)
last = numbers.pop()
print(last, numbers)
first = numbers.pop(0)
print(first, numbers)[5, 2, 9, 1]
1 [5, 2, 9]
5 [2, 9]scores = [88, 45, 97, 62]
scores.sort()
print(scores)
scores.reverse()
print(scores)
scores.extend([100, 30])
print(scores)[45, 62, 88, 97]
[97, 88, 62, 45]
[97, 88, 62, 45, 100, 30]remove() deletes by value and raises a ValueError if the value is not found. pop() deletes by index and raises an IndexError for an invalid index. Do not confuse the two.
Mixed-Type Lists
Unlike arrays in some other languages, a single Python list can freely mix different data types — strings, integers, floats, booleans, even other lists.
mixed = ["Amol", 22, 5.9, True, ["nested", "list"]]
print(mixed)
for item in mixed:
print(item, "->", type(item))['Amol', 22, 5.9, True, ['nested', 'list']]
Amol -> <class 'str'>
22 -> <class 'int'>
5.9 -> <class 'float'>
True -> <class 'bool'>
['nested', 'list'] -> <class 'list'>Copying a List Correctly
One of the most common bugs for beginners is assuming that writing new_list = old_list creates a copy. It does not — it creates a second name pointing at the exact same list in memory. This is called aliasing, and changing one variable changes the other too.
original = [1, 2, 3]
alias = original
alias.append(4)
print(original)
print(alias)[1, 2, 3, 4]
[1, 2, 3, 4]To make an independent copy, use the .copy() method or slicing with [:]. Changes to the copy will no longer affect the original.
original = [1, 2, 3]
copy_one = original.copy()
copy_two = original[:]
copy_one.append(4)
copy_two.append(5)
print(original)
print(copy_one)
print(copy_two)[1, 2, 3]
[1, 2, 3, 4]
[1, 2, 3, 5]Always use .copy() or [:] when you need an independent list. Simply writing new_list = old_list is one of the most common sources of confusing bugs for beginners, since both names refer to the same list object.
Nested Lists
A list can contain other lists as items, which is useful for representing grids, tables, or grouped data. You access nested items by chaining indices.
grid = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(grid[0])
print(grid[1][2])[1, 2, 3]
6Checking Membership with in
Just like with strings, the in keyword checks whether a value exists inside a list.
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits)
print("mango" in fruits)True
FalseCommon Mistakes
- Assuming new_list = old_list makes a copy — it only creates an alias to the same list.
- Using remove() with a value that is not in the list, causing a ValueError.
- Confusing append() (adds one item) with extend() (adds each item from an iterable).
- Forgetting that pop() without an argument removes the last item, not the first.
- Mutating a list while looping over it directly, which can skip items unexpectedly.
Best Practices
- Use .copy() or [:] whenever you need an independent list.
- Prefer append() for single items and extend() for combining lists.
- Use descriptive plural names for lists, like fruits or scores.
- Use sort() when you want to keep the original list changed, or sorted() when you want a new list back.
- Keep nested lists simple — consider a dictionary if items need named fields.
Frequently Asked Questions
What is the difference between a list and a string?
A string is an immutable sequence of characters, while a list is a mutable sequence that can hold any type of item and be changed after creation.
How do I create a truly independent copy of a list?
Use my_list.copy() or my_list[:]. Writing new_list = my_list only creates a second reference to the same list.
What is the difference between sort() and sorted()?
list.sort() sorts the list in place and returns None, while the built-in sorted(list) returns a brand-new sorted list and leaves the original unchanged.
Can a list contain another list?
Yes, this is called a nested list and is commonly used to represent grids or tables of data.
How do I remove all items from a list?
Use my_list.clear(), which empties the list in place.
Key Takeaways
- Lists are ordered, mutable collections created with square brackets.
- Indexing and slicing work the same way as with strings.
- append, insert, remove, pop, sort, reverse, and extend are the core list methods.
- A single list can hold mixed data types, including other lists.
- Assigning a list to a new variable creates an alias, not a copy — use .copy() or [:] instead.
- The in keyword checks membership just like it does for strings.
Summary
Lists are one of the most versatile and frequently used data structures in Python, letting you store, modify, and organize collections of data with a rich set of built-in methods.
Next, you will learn about tuples — a close cousin of the list that trades mutability for safety and performance in specific situations.
- You can create, index, and slice lists.
- You know the core list methods for adding, removing, and reorganizing items.
- You understand the aliasing pitfall and how to copy a list correctly.
- You are ready to learn about tuples.