Lists and Tuples in Python
Understanding Sequence Types
Lists and tuples are fundamental sequence data types in Python. They both store ordered collections of items, but with key differences in mutability, performance, and use cases.
Both can contain elements of different data types, including other lists or tuples, and support indexing, slicing, and iteration operations.
# Lists use square brackets fruits = ["apple", "banana", "cherry"] # Tuples use parentheses coordinates = (10, 20) # Both allow indexing print(fruits[0]) # "apple" print(coordinates[1]) # 20 # Both allow slicing print(fruits[1:3]) # ["banana", "cherry"] # Key difference: mutability fruits[0] = "apricot" # Valid - lists are mutable # coordinates[0] = 30 # Invalid - tuples are immutable
Python Lists in Detail
List Creation and Basics
Lists are mutable, ordered sequences of elements. Each element can be of any data type.
They're created with square brackets or the list()
constructor.
# Creating lists empty_list = [] numbers = [1, 2, 3, 4, 5] mixed = [1, "hello", 3.14, True] nested = [1, [2, 3], [4, [5, 6]]] # List constructor from_range = list(range(5)) # [0, 1, 2, 3, 4] from_string = list("hello") # ['h', 'e', 'l', 'l', 'o'] from_tuple = list((1, 2, 3)) # [1, 2, 3] # Accessing elements first = numbers[0] # 1 last = numbers[-1] # 5 middle = numbers[1:4] # [2, 3, 4]
List Methods and Operations
Lists provide numerous methods for adding, removing, and manipulating elements.
# Adding elements fruits = ["apple", "banana"] fruits.append("cherry") # Add to end: ['apple', 'banana', 'cherry'] fruits.insert(1, "orange") # Insert at index: ['apple', 'orange', 'banana', 'cherry'] fruits.extend(["mango", "kiwi"]) # Add multiple items: ['apple', 'orange', 'banana', 'cherry', 'mango', 'kiwi'] # Removing elements fruits.remove("banana") # Remove by value last_fruit = fruits.pop() # Remove and return last item: 'kiwi' second_fruit = fruits.pop(1) # Remove by index: 'orange' fruits.clear() # Remove all items: [] # Finding elements numbers = [10, 20, 30, 20, 40] print(numbers.index(20)) # 1 (first occurrence) print(numbers.count(20)) # 2 (number of occurrences) # Sorting and reversing names = ["Charlie", "Alice", "Bob"] names.sort() # In-place sort: ['Alice', 'Bob', 'Charlie'] names.sort(reverse=True) # Descending sort: ['Charlie', 'Bob', 'Alice'] names.reverse() # In-place reverse: ['Alice', 'Bob', 'Charlie'] # Sorted copy sorted_copy = sorted(names) # Returns new list, doesn't modify original
List Slicing and Copying
Slicing lets you extract portions of a list. It's a powerful feature for manipulating sequences.
# Slicing syntax: list[start:stop:step] numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] print(numbers[2:5]) # [2, 3, 4] print(numbers[:3]) # [0, 1, 2] print(numbers[7:]) # [7, 8, 9] print(numbers[1:8:2]) # [1, 3, 5, 7] print(numbers[::-1]) # [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] (reversed) # Copying lists shallow_copy1 = numbers[:] # Slice copy shallow_copy2 = numbers.copy() # Method copy shallow_copy3 = list(numbers) # Constructor copy # Deep copying (for nested lists) import copy nested = [[1, 2], [3, 4]] deep_copy = copy.deepcopy(nested)
List Comprehensions
List comprehensions provide a concise way to create lists based on existing lists or other iterables.
# Basic list comprehension squares = [x**2 for x in range(10)] print(squares) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] # With condition even_squares = [x**2 for x in range(10) if x % 2 == 0] print(even_squares) # [0, 4, 16, 36, 64] # Nested list comprehension matrix = [[j for j in range(3)] for i in range(3)] print(matrix) # [[0, 1, 2], [0, 1, 2], [0, 1, 2]] # With if/else values = [x if x % 2 == 0 else -x for x in range(10)] print(values) # [0, -1, 2, -3, 4, -5, 6, -7, 8, -9]
Python Tuples in Detail
Tuple Creation and Basics
Tuples are immutable, ordered sequences of elements. Once created, their values cannot be changed.
They're created with parentheses or the tuple()
constructor.
# Ways to create tuples empty_tuple = () single_item = (1,) # Note the comma! Without it, it's just an int in parentheses coordinates = (10, 20, 30) mixed_tuple = (1, "hello", 3.14) from_constructor = tuple([1, 2, 3]) # (1, 2, 3) from_string = tuple("hello") # ('h', 'e', 'l', 'l', 'o') # Tuple size and membership print(len(coordinates)) # 3 print(20 in coordinates) # True
Tuple Methods and Operations
Since tuples are immutable, they have fewer methods than lists, but they still support many operations.
# Accessing elements coordinates = (10, 20, 30) print(coordinates[0]) # 10 print(coordinates[-1]) # 30 # Slicing works like lists print(coordinates[1:]) # (20, 30) # Only two methods values = (1, 2, 2, 3, 4, 2) print(values.count(2)) # 3 (occurrences of 2) print(values.index(3)) # 3 (index of first 3) # Concatenation and repetition tuple1 = (1, 2) tuple2 = (3, 4) combined = tuple1 + tuple2 # (1, 2, 3, 4) repeated = tuple1 * 3 # (1, 2, 1, 2, 1, 2)
Tuple Unpacking
One of the most powerful features of tuples is their ability to be unpacked into multiple variables.
# Basic unpacking point = (10, 20, 30) x, y, z = point print(x, y, z) # 10 20 30 # Unpacking with rest operator (*) numbers = (1, 2, 3, 4, 5) first, *middle, last = numbers print(first) # 1 print(middle) # [2, 3, 4] print(last) # 5 # Swapping values a, b = 5, 10 a, b = b, a # Now a is 10, b is 5 # Function returning multiple values (as a tuple) def get_dimensions(): return 1920, 1080 # Returns a tuple (1920, 1080) width, height = get_dimensions() print(f"Width: {width}, Height: {height}") # Width: 1920, Height: 1080
Named Tuples
Named tuples enhance regular tuples by allowing you to access elements by name instead of just index.
# Named tuples from collections module from collections import namedtuple # Define a new type Point = namedtuple('Point', ['x', 'y', 'z']) # Create an instance point = Point(10, 20, 30) # Access by name or index print(point.x) # 10 (by name) print(point[1]) # 20 (by index) print(point._asdict()) # {'x': 10, 'y': 20, 'z': 30} (as dictionary) # Named tuples are immutable # point.x = 100 # AttributeError # But you can create a new one with _replace new_point = point._replace(x=100) print(new_point) # Point(x=100, y=20, z=30)
Lists vs Tuples: When to Use Which
Each has its strengths and ideal use cases. Understanding when to use each can lead to more efficient and maintainable code.
Feature | List | Tuple |
---|---|---|
Mutability | Mutable (can change) | Immutable (fixed) |
Syntax | Square brackets `[]` | Parentheses `()` |
Size | Dynamic | Fixed |
Memory | More overhead | Less overhead |
Performance | Slower | Faster |
Methods | Many (append, remove, etc.) | Few (count, index) |
Use as Dictionary Key | No (not hashable) | Yes (hashable) |
When to Use Lists
- When the collection needs to be modified (adding/removing elements)
- For homogeneous collections that may grow or shrink
- When you need to use methods like sort, reverse, etc.
- For data that represents a collection of similar items
When to Use Tuples
- For fixed data that shouldn't change
- As dictionary keys (since they're hashable)
- For heterogeneous data that forms a single logical item
- For returning multiple values from a function
- For data that's meant to be unpacked
# Use a list when the collection will change shopping_cart = ["apple", "milk", "bread"] shopping_cart.append("eggs") # Use a tuple for fixed, structured data person = ("John Doe", 35, "Developer") name, age, occupation = person # Tuples can be used as dictionary keys locations = { (40.7128, -74.0060): "New York", (34.0522, -118.2437): "Los Angeles" } print(locations[(40.7128, -74.0060)]) # "New York" # Lists cannot be used as dictionary keys # locations[[40.7128, -74.0060]] = "New York" # TypeError: unhashable type: 'list'
Comparison: Lists vs. Tuples
Feature | Lists | Tuples |
---|---|---|
Mutability | Mutable (can be changed) | Immutable (cannot be changed) |
Syntax | Square brackets [] |
Parentheses () |
Size | More memory (resizable) | Less memory (fixed size) |
Memory usage | Higher (extra memory for resizing) | Lower (exactly what's needed) |
Performance | Slower | Faster |
Methods | Many (append, extend, insert, remove...) | Few (count, index) |
Dict keys | Cannot be dictionary keys | Can be dictionary keys |
Practice Exercises
Try These:
- Create a function that takes a list and returns a new list with unique elements of the first list.
- Write a Python program to find the second largest number in a list.
- Create a function that counts the number of elements in a list without using len().
- Write a function to flatten a nested list into a single list.
- Create a named tuple for representing a 3D point and use it to calculate the distance between two points.