Learning Guides
Lists in Python: Complete Guide with Examples
Quick answer: Learn Python lists in depth including creation, indexing, slicing, methods, list comprehension, mutability, nested lists, and common interview questions.
A list is one of the most commonly used data structures in Python. It is an ordered, mutable collection that can hold items of any type, and it is the natural starting point for almost anyone learning Python for data work.
In this guide you will learn:
How to create and access lists
Indexing and slicing
The most useful list methods
List comprehension
Mutability and how it can surprise you
Nested lists
Interview questions
Creating a List
fruits = ['apple', 'banana', 'cherry']
numbers = [10, 20, 30, 40]
mixed = ['Fireblaze', 89000, True, 4.5]
empty = []
A single Python list can hold different data types at once, which is not true of every language's array type.
Indexing
Python indexing starts at 0, and negative indices count from the end.
fruits = ['apple', 'banana', 'cherry', 'mango']
print(fruits[0]) # apple
print(fruits[2]) # cherry
print(fruits[-1]) # mango (last item)
print(fruits[-2]) # cherry (second last)
Slicing
Slicing extracts a sub-list using list[start:stop:step]. The start is included, the stop is not.
numbers = [10, 20, 30, 40, 50, 60]
print(numbers[1:4]) # [20, 30, 40]
print(numbers[:3]) # [10, 20, 30]
print(numbers[3:]) # [40, 50, 60]
print(numbers[::2]) # [10, 30, 50] every second item
print(numbers[::-1]) # [60, 50, 40, 30, 20, 10] reversed
Common List Methods
Adding items
fruits = ['apple', 'banana']
fruits.append('cherry') # adds to the end -> ['apple', 'banana', 'cherry']
fruits.insert(1, 'mango') # inserts at index 1 -> ['apple', 'mango', 'banana', 'cherry']
fruits.extend(['grape', 'kiwi']) # adds multiple items at the end
Removing items
fruits = ['apple', 'banana', 'cherry', 'banana']
fruits.remove('banana') # removes the FIRST matching value -> ['apple', 'cherry', 'banana']
last = fruits.pop() # removes and returns the last item
first = fruits.pop(0) # removes and returns the item at index 0
fruits.clear() # empties the list completely
Searching and counting
numbers = [10, 20, 30, 20, 40]
print(numbers.index(20)) # 1 (first occurrence)
print(numbers.count(20)) # 2 (how many times 20 appears)
print(20 in numbers) # True
Sorting and reversing
numbers = [40, 10, 30, 20]
numbers.sort() # sorts in place -> [10, 20, 30, 40]
numbers.sort(reverse=True) # descending -> [40, 30, 20, 10]
numbers.reverse() # reverses current order in place
# sorted() returns a NEW list and leaves the original unchanged
original = [3, 1, 2]
new_list = sorted(original)
List Comprehension
List comprehension is a concise way to build a list from an existing iterable.
numbers = [1, 2, 3, 4, 5, 6]
squares = [n ** 2 for n in numbers]
# [1, 4, 9, 16, 25, 36]
even_squares = [n ** 2 for n in numbers if n % 2 == 0]
# [4, 16, 36]
labels = ['even' if n % 2 == 0 else 'odd' for n in numbers]
# ['odd', 'even', 'odd', 'even', 'odd', 'even']
The general pattern is [expression for item in iterable if condition]. It is usually faster and more readable than the equivalent for loop with repeated append calls.
Mutability: The Part That Surprises Beginners
Lists are mutable, which means they can be changed after creation. This has a consequence that catches almost everyone out at least once.
list_a = [1, 2, 3]
list_b = list_a # list_b now points to the SAME list, not a copy
list_b.append(4)
print(list_a) # [1, 2, 3, 4] -- list_a changed too!
Assigning one variable to another does not create a copy. Both names simply point to the same underlying list object.
How to actually copy a list
import copy
original = [1, 2, [3, 4]]
shallow = original.copy() # or list(original) or original[:]
deep = copy.deepcopy(original) # copies nested objects too
A shallow copy creates a new outer list, but any nested lists inside it are still shared with the original. A deep copy recursively copies everything, so nested objects are fully independent.
Nested Lists
Lists can contain other lists, which is how simple grid or table-like structures are represented in plain Python.
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(matrix[1]) # [4, 5, 6]
print(matrix[1][2]) # 6
List vs Tuple
This distinction is one of the most frequently asked Python questions.
| List | Tuple |
|---|---|
| Mutable, can be changed after creation | Immutable, cannot be changed |
| Written with square brackets [] | Written with parentheses () |
| Slightly slower | Slightly faster, and hashable so it can be used as a dictionary key |
| Used when the collection may need to change | Used for fixed collections, such as coordinates |
A Few Practical Notes
append() adds one item to the end and is very efficient
insert() at the beginning of a large list is slower, since every following item has to shift position
Checking membership with in on a list is slower than on a set for large collections, because a list is searched item by item
len(my_list) returns the number of items
Common Interview Questions
What is the difference between append and extend?
a = [1, 2, 3]
a.append([4, 5]) # [1, 2, 3, [4, 5]] -- adds the list as ONE item
b = [1, 2, 3]
b.extend([4, 5]) # [1, 2, 3, 4, 5] -- adds each item individually
What is the difference between remove and pop?
remove() deletes the first item that matches a given value. pop() deletes the item at a given index, or the last item by default, and also returns the removed value.
How do you remove duplicates from a list?
numbers = [1, 2, 2, 3, 3, 3, 4]
unique = list(set(numbers)) # [1, 2, 3, 4]
Note that converting to a set does not preserve the original order. If order matters, use a loop or dict.fromkeys() instead.
What is the time complexity of common list operations?
| Operation | Typical complexity |
|---|---|
| Access by index | O(1) |
| append at the end | O(1) |
| insert or pop at the beginning | O(n) |
| Search with in | O(n) |
Why does list_b = list_a not create a copy?
In Python, variables are references to objects, not the objects themselves. Assignment copies the reference, not the underlying data, so both names point to the same list in memory.
Final Thoughts
Lists are the default, general purpose collection in Python and one of the very first things any Data Analyst or Data Science learner needs to be completely comfortable with. Indexing, slicing, the core methods and list comprehension cover the large majority of everyday use.
The one habit worth building early is being deliberate about copying. Knowing exactly when you have a shared reference versus a genuine independent copy will save you from a category of bug that looks confusing the first time and completely obvious once you understand why it happens.
FAQ
Frequently Asked Questions
What is the difference between append and extend in Python?
append() adds its argument as a single item to the end of the list. extend() adds each item from an iterable individually.
What is the difference between remove and pop for lists?
remove() deletes the first item matching a given value. pop() deletes the item at a given index, or the last item by default, and also returns the removed value.
How do you remove duplicates from a list?
Convert it to a set with list(set(my_list)), though this does not preserve the original order. Use a loop or dict.fromkeys() if order matters.
Why does list_b = list_a not create a copy?
In Python, variables are references to objects, not the objects themselves. Assignment copies the reference, not the underlying data, so both names point to the same list in memory.
Keep Reading
Related Articles
Learning Guides
INNER JOIN in SQL with Examples: Complete Beginner's Guide
Learn INNER JOIN in SQL with practical examples, syntax, interview questions, and real-world use cases. A complete beginner-friendly SQL JOI
Learning Guides
OUTER JOIN in SQL: Complete Guide with Examples for Beginners
Master OUTER JOIN in SQL with practical examples and real-world scenarios. Learn LEFT JOIN, RIGHT JOIN, FULL OUTER JOIN, syntax, use cases,
Learning Guides
Multi-Row Functions in SQL: Complete Guide with Examples
Learn multi-row (aggregate) functions in SQL including SUM, AVG, COUNT, MIN, MAX, GROUP BY and HAVING, with practical examples, NULL handlin