6.3. List Operations#
This section covers how to work with lists using
operators,
built-in functions, and
methods.
import sys
from pathlib import Path
# Find project root by looking for _config.yml
current = Path.cwd()
for parent in [current, *current.parents]:
if (parent / '_config.yml').exists():
project_root = parent
break
else:
project_root = Path.cwd().parent.parent
# Add project root to path
sys.path.insert(0, str(project_root))
# Import shared teaching helpers and cell magics
from shared import thinkpython, diagram, jupyturtle, structshape
from shared.download import download
fruits = ['apple', 'banana', 'cherry']
6.3.1. List Operators#
Python supports several operators that work directly with lists:
Operator |
Name |
Description |
Example |
Result |
|---|---|---|---|---|
|
Concatenation |
Combines two lists |
|
|
|
Repetition |
Repeats a list |
|
|
|
Membership |
Checks if item exists in list |
|
|
|
Non-membership |
Checks if item doesn’t exist |
|
|
|
Indexing |
Accesses element by position |
|
|
|
Slicing |
Extracts portion of list |
|
|
|
Equality |
Checks if lists are equal |
|
|
|
Inequality |
Checks if lists are not equal |
|
|
|
Less than |
Lexicographic comparison |
|
|
|
Greater than |
Lexicographic comparison |
|
|
|
Less than or equal |
Lexicographic comparison |
|
|
|
Greater than or equal |
Lexicographic comparison |
|
|
The + operator concatenates lists.
num1 = [1, 2, 3]
num2 = [4, 5, 6]
num1 + num2
[1, 2, 3, 4, 5, 6]
The * operator repeats a list a given number of times.
['spam'] * 4
['spam', 'spam', 'spam', 'spam']
### EXERCISE: List Concatenation and Repetition
# 1. Create two lists: list1 = [1, 2, 3] and list2 = [4, 5, 6]
# 2. Concatenate them to create list3
# 3. Create list4 by repeating [0] three times
### Your code starts here:
### Your code ends here.
List1 + List2: [1, 2, 3, 4, 5, 6]
[0] * 3: [0, 0, 0]
6.3.1.1. Membership Testing#
The in operator checks whether a given element appears anywhere in the list.
'apple' in fruits
True
print('tomato' in fruits)
print('tomato' not in fruits)
False
True
When checking membership with in, only top-level elements are considered. For example, 'spam' is in nested mixed_list, but 10 is not (since it’s inside a nested list):
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
mixed_list = ['spam', 2.0, 5, numbers ]
print('spam' in mixed_list) ### True
print(10 in mixed_list) ### False
True
False
### EXERCISE: Membership Testing
inventory = ['apple', 'banana', 'orange', 'grape', 'mango']
# 1. Check if 'orange' is in the inventory
# 2. Check if 'strawberry' is NOT in the inventory
# 3. Create a list of items to check: ['apple', 'kiwi', 'grape']
# and count how many of them are in inventory using a
# LIST COMPREHENSION and sum()
### Your code starts here:
### Your code ends here.
Has orange: True
No strawberry: True
Items found in inventory: 2
6.3.2. List Methods/Functions#
Python provides many built-in methods and functions that operate on lists. Common list methods and functions include:
Purpose |
Function/Method |
Description |
Example |
Result |
|---|---|---|---|---|
Creating/Copying |
|
Creates a new list |
|
|
|
Returns shallow copy |
|
|
|
Adding Items |
|
Adds single item to end |
|
|
|
Inserts item at position |
|
|
|
|
Adds all items from iterable |
|
|
|
Removing Items |
|
Removes first occurrence of value |
|
|
|
Removes and returns last item |
|
Returns |
|
|
Removes and returns item at index |
|
Returns |
|
|
Removes all items |
|
|
|
Searching/Counting |
|
Returns index of first occurrence |
|
|
|
Counts occurrences of value |
|
|
|
Sorting/Reversing |
|
Sorts list in place |
|
|
|
Returns new sorted list |
|
|
|
|
Reverses list in place |
|
|
|
|
Returns reverse iterator |
|
|
|
Information/Statistics |
|
Returns number of items |
|
|
|
Returns largest item |
|
|
|
|
Returns smallest item |
|
|
|
|
Returns sum of numeric items |
|
|
Let’s explore some of these with examples:
6.3.2.1. List Functions#
Python provides several built-in functions that work with lists to perform common operations, such as finding the length (len()), maximum (max()), minimum (min()), sum (sum()), sorting (sorted()), and type conversion (list()).
The len function returns the length of a list as the count of number of the elements.
numbers = [1, 2, 3, 4, 5]
fruits = ['apple', 'banana', 'cherry', 'date', 'elderberry']
print(f"There are {len(numbers)} numbers in {numbers}.")
print(f"There are {len(fruits)} fruits in {fruits}.")
There are 5 numbers in [1, 2, 3, 4, 5].
There are 5 fruits in ['apple', 'banana', 'cherry', 'date', 'elderberry'].
The length of an empty list is 0.
empty = []
len(empty)
0
No other mathematical operators work with lists, but the built-in function sum adds up the elements.
And the min and max functions find the smallest and largest elements.
num1 = [1, 2, 3]
num2 = [4, 5, 6]
print(sum(num1))
print(min(num1))
print(max(num2))
6
1
6
6.3.3. List Modifying Methods#
Lists have built-in methods that allow you to modify them in place, such as adding, removing, or reordering elements.
letters = ['a', 'b', 'c', 'd']
print(f"Original list:\t\t {letters}")
# append() - Adds element to the end
letters.append('e')
print(f"After append 'e':\t {letters}")
# extend() - Appends all elements from another list
letters.extend(['f', 'g'])
print(f"After extend ['f', 'g']: {letters}")
# insert() - Inserts element at specific position
letters.insert(0, 'z')
print(f"After insert at 0:\t {letters}")
# remove() - Removes first occurrence of element
letters.remove('z')
print(f"After remove 'z':\t {letters}")
# pop() - Removes and returns element at index (or last if no index)
last_item = letters.pop()
print(f"Popped: {last_item}, Remaining:\t {letters}")
# clear() - Removes all elements
temp = [1, 2, 3]
temp.clear()
print(f"After clear:\t\t {temp}")
Original list: ['a', 'b', 'c', 'd']
After append 'e': ['a', 'b', 'c', 'd', 'e']
After extend ['f', 'g']: ['a', 'b', 'c', 'd', 'e', 'f', 'g']
After insert at 0: ['z', 'a', 'b', 'c', 'd', 'e', 'f', 'g']
After remove 'z': ['a', 'b', 'c', 'd', 'e', 'f', 'g']
Popped: g, Remaining: ['a', 'b', 'c', 'd', 'e', 'f']
After clear: []
Note: If you try to remove() an element that doesn’t exist, Python raises a ValueError. If you try to pop() from an empty list, Python raises an IndexError.
6.3.4. Iteration Helpers: enumerate and zip#
Using enumerate()
When looping through a list, you sometimes need to know both the element and its index. The enumerate() function returns pairs of (index, element) for each item in the list.
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
0: apple
1: banana
2: cherry
Using zip()
The zip() function is useful when you need to loop through two or more lists in parallel. It pairs up elements from each list and returns tuples.
names = ['Alice', 'Bob', 'Charlie']
ages = [25, 30, 35]
cities = ['New York', 'London', 'Tokyo']
for name, age, city in zip(names, ages, cities):
print(f"{name} is {age} years old and lives in {city}")
Alice is 25 years old and lives in New York
Bob is 30 years old and lives in London
Charlie is 35 years old and lives in Tokyo
test = zip(names, ages, cities)
print(test) # This will print a zip object, not the contents
print(list(test)) # Convert zip object to list to see contents
test2 = zip(names, ages)
print(dict(test2)) # Convert to dict to see contents (keys from names, values from ages)
<zip object at 0x10c7e7000>
[('Alice', 25, 'New York'), ('Bob', 30, 'London'), ('Charlie', 35, 'Tokyo')]
{'Alice': 25, 'Bob': 30, 'Charlie': 35}
### EXERCISE: Using List Methods
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
# 1. Count how many times 1 appears in the list
# 2. Append the number 7 to the end
# 3. Remove the first occurrence of 1
# 4. Find the index of the number 5
### Your code starts here:
### Your code ends here.
Count of 1s: 2
List after appending 7: [3, 1, 4, 1, 5, 9, 2, 6, 7]
List after removing first occurrence of 1: [3, 4, 1, 5, 9, 2, 6, 7]
Index of 5: 3
### EXERCISE: Using enumerate() and zip()
### with the following lists:
fruits = ['apple', 'banana', 'cherry']
prices = [10, 20, 30]
# 1. Use enumerate() to print the index and fruit name
# as "0: apple", "1: banana", etc.
# 2. Use zip() to print each fruit with its corresponding price
# as "apple costs 10", "banana costs 20", etc.
### Your code starts here:
### Your code ends here.
0: apple
1: banana
2: cherry
apple costs 10
banana costs 20
cherry costs 30
6.3.5. List Unpacking#
Unpacking is a Python feature that allows you to assign multiple values from a list (or any iterable) to multiple variables in a single statement. Instead of accessing elements one by one with indexing, you can extract them all at once.
This makes your code more readable and Pythonic, especially when working with structured data.
6.3.5.1. Basic Unpacking#
# Without unpacking (verbose)
point = [10, 20, 30]
x = point[0]
y = point[1]
z = point[2]
# With unpacking (concise)
point = [10, 20, 30]
x, y, z = point ### assigns 10 to x, 20 to y, 30 to z
# Unpacking actually works with any iterable
first, second = "hi"
print(f"first={first}, second={second}")
first=h, second=i
6.3.5.2. With Star Operator#
Using
*(the unpacking operator) allows you to capture multiple elements.You can only have one
*variableper unpacking statement.
# Capture the first element and the rest
numbers = [1, 2, 3, 4, 5]
first, *rest = numbers
print(f"First: {first}")
print(f"Rest: {rest}")
First: 1
Rest: [2, 3, 4, 5]
# Capture first, last, and middle
first, *middle, last = numbers
print(f"First: {first}, Middle: {middle}, Last: {last}")
First: 1, Middle: [2, 3, 4], Last: 5
# Capture last element
*most, last = numbers
print(f"Most: {most}, Last: {last}")
Most: [1, 2, 3, 4], Last: 5
### Unpacking works with all iterables, including
### a string into individual characters
word = "Python"
first, *middle, last = word
print(f"First: {first}")
print(f"Middle: {middle}")
print(f"Last: {last}")
First: P
Middle: ['y', 't', 'h', 'o']
Last: n
6.3.5.3. Unpacking in Function Calls#
The * operator can also unpack a list into function arguments:
# Unpack a list as function arguments
def display_info(name, age, city):
print(f"{name} is {age} years old and lives in {city}")
person = ['Alice', 30, 'New York']
display_info(*person) ### unpacks to display_info('Alice', 30, 'New York')
Alice is 30 years old and lives in New York
# Useful with functions like print
values = [1, 2, 3, 4, 5]
print(*values) # Prints: 1 2 3 4 5 (separated by spaces)
print(*values, sep='-') # Prints: 1-2-3-4-5
1 2 3 4 5
1-2-3-4-5
Common use cases:
Swapping values:
a, b = b, aParsing CSV data:
name, age, email = row.split(',')Function returns:
min_val, max_val = find_min_max(numbers)Ignoring values:
first, *_, last = data(use_for values you don’t need)
Note:
_in*_is used as a throwaway variable name, it’s a Python convention meaning “I don’t care about this value.”