You need Python installed, and to know how to run a
.py file. If python3 --version in a
terminal prints a version number, you are ready. If it does not — or
if you have never opened a terminal — do
Getting Started with
Python first; it installs Python and runs your first program, and
takes about fifteen minutes. Nothing else is needed: no account, no
payment, no extra software.
Lists
A list is an ordered, mutable collection of items. Lists are one of the most versatile data structures in Python — you'll use them constantly.
# Creating lists
fruits = ["apple", "banana", "cherry"]
numbers = [1, 2, 3, 4, 5]
mixed = ["hello", 42, True, 3.14]
empty = []
Accessing List Items
colors = ["red", "green", "blue", "yellow"]
print(colors[0]) # red (first item)
print(colors[-1]) # yellow (last item)
print(colors[1:3]) # ['green', 'blue'] (slicing)
Modifying Lists
fruits = ["apple", "banana", "cherry"]
# Add items
fruits.append("mango") # Add to end
fruits.insert(1, "grape") # Insert at index 1
# Remove items
fruits.remove("banana") # Remove by value
popped = fruits.pop() # Remove and return last item
del fruits[0] # Remove by index
# Change items
fruits[0] = "kiwi" # Replace item at index
Useful List Methods
numbers = [3, 1, 4, 1, 5, 9, 2]
numbers.sort() # [1, 1, 2, 3, 4, 5, 9]
numbers.reverse() # [9, 5, 4, 3, 2, 1, 1]
print(len(numbers)) # 7
print(numbers.count(1)) # 2 (how many 1s)
print(numbers.index(5)) # 1 (position of 5)
# Check if item exists
if 5 in numbers:
print("Found it!")
A compact way to create lists from existing ones:
squares = [x**2 for x in range(1, 6)]
# [1, 4, 9, 16, 25]
evens = [x for x in range(20) if x % 2 == 0]
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
Tuples
Tuples are like lists but immutable — once created, they cannot be changed. Use tuples for data that shouldn't be modified.
# Creating tuples
coordinates = (10, 20)
rgb_color = (255, 128, 0)
single = (42,) # Note the trailing comma for single-item tuple
# Accessing items (same as lists)
print(coordinates[0]) # 10
print(rgb_color[-1]) # 0
# Unpacking tuples
x, y = coordinates
print(f"x={x}, y={y}") # x=10, y=20
coordinates[0] = 99 will raise a TypeError.
If you need to change values, use a list instead, or create a new tuple.
When to Use Tuples vs Lists
- Lists — for collections that change (shopping list, to-do items, user input)
- Tuples — for fixed data (coordinates, RGB colors, database rows, function return values)
Dictionaries
Dictionaries store data as key-value pairs. Instead of accessing items by index number, you access them by their key name.
# Creating a dictionary
user = {
"name": "Alice",
"age": 25,
"email": "alice@example.com",
"is_admin": False
}
# Accessing values
print(user["name"]) # Alice
print(user.get("age")) # 25
print(user.get("phone", "N/A")) # N/A (default if key doesn't exist)
Modifying Dictionaries
user = {"name": "Alice", "age": 25}
# Add or update
user["email"] = "alice@example.com" # Add new key
user["age"] = 26 # Update existing key
# Remove
del user["email"] # Remove by key
removed = user.pop("age") # Remove and return value
# Check if key exists
if "name" in user:
print("Name is set")
Iterating Over Dictionaries
scores = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Loop through keys
for name in scores:
print(name)
# Loop through values
for score in scores.values():
print(score)
# Loop through both
for name, score in scores.items():
print(f"{name}: {score}")
# Output:
# Alice: 95
# Bob: 87
# Charlie: 92
Useful Dictionary Methods
config = {"host": "localhost", "port": 8080, "debug": True}
print(config.keys()) # dict_keys(['host', 'port', 'debug'])
print(config.values()) # dict_values(['localhost', 8080, True])
print(len(config)) # 3
# Merge two dictionaries
defaults = {"host": "localhost", "port": 80}
custom = {"port": 8080, "debug": True}
merged = {**defaults, **custom}
# {'host': 'localhost', 'port': 8080, 'debug': True}
Nested Data Structures
You can nest lists, tuples, and dictionaries inside each other:
# List of dictionaries (very common pattern)
users = [
{"name": "Alice", "age": 25},
{"name": "Bob", "age": 30},
{"name": "Charlie", "age": 28}
]
for user in users:
print(f"{user['name']} is {user['age']} years old")
# Dictionary with lists
student = {
"name": "Alice",
"grades": [95, 87, 92, 88],
"subjects": ["Math", "Science", "English"]
}
average = sum(student["grades"]) / len(student["grades"])
print(f"Average: {average}") # Average: 90.5
Practical Example: Contact Book
contacts = {}
def add_contact(name, phone):
contacts[name] = phone
print(f"Added {name}")
def find_contact(name):
if name in contacts:
print(f"{name}: {contacts[name]}")
else:
print(f"{name} not found")
def list_contacts():
if not contacts:
print("No contacts yet")
return
for name, phone in sorted(contacts.items()):
print(f" {name}: {phone}")
# Usage
add_contact("Alice", "555-0101")
add_contact("Bob", "555-0202")
find_contact("Alice") # Alice: 555-0101
list_contacts()
# Output:
# Alice: 555-0101
# Bob: 555-0202
Now Do It Yourself: Five Steps
Lists and dictionaries are how Python holds more than one thing at a time. You will build a shopping list, price it up, and total it. Every output below is exactly what Python printed — including one surprise about decimals.
Go: open a terminal, run cd ~, then start Python with python3.
Do: at the >>> prompt, type these three lines.
items = ["bread", "milk"]
items.append("eggs")
print(items, len(items), items[0], items[-1])
You should see: ['bread', 'milk', 'eggs'] 3 bread eggs. Positions start at 0, so items[0] is the first; -1 counts from the right, so it is always the last however long the list grows.
If not: AttributeError: 'list' object has no attribute 'add' means you wrote add — lists use append. And note append changed items in place and returned nothing: writing items = items.append("eggs") would leave you holding None. Lists behave the opposite way to strings here.
Go: same prompt.
Do: type print(items[5]) and press Enter. This is meant to fail.
You should see: IndexError: list index out of range. The list holds three things, so the only valid positions are 0, 1 and 2. Python will not invent a fourth or hand back an empty value.
If not: if something prints, your list is longer than you think — run len(items) to see. Getting this error deliberately once is worth it: in real code it almost always means a loop counted one too far.
Go: same prompt.
Do: type these four lines.
prices = {"bread": 2.50, "milk": 1.20}
prices["eggs"] = 3.00
print(prices["bread"], len(prices))
for k, v in prices.items():
print(k, v)
You should see: 2.5 3, then bread 2.5, milk 1.2, eggs 3.0. Two things to notice. A dictionary is looked up by label rather than position. And 2.50 printed as 2.5 — Python stores the number, not the way you typed it. Trailing zeros are a display choice, and you add them back with formatting when you show money to a person.
If not: SyntaxError usually means a missing colon between key and value, or a comma left out between pairs. Unlike a list, every entry here is a pair joined by :.
Go: same prompt.
Do: type print(prices["cheese"]), then afterwards type print(prices.get("cheese", "not stocked")).
You should see: first KeyError: 'cheese', then not stocked. Same missing key, two behaviours: square brackets insist the key exists, get accepts that it might not and lets you supply a fallback.
If not: if the first one prints a price, the key is there already — try a word you have definitely not used. Choosing between these two deliberately is the habit that matters: use brackets when a missing key is a bug you want to hear about, and get when it is a normal possibility.
Go: leave the prompt with exit() and create a file called basket.py.
Do: type these three lines and run python3 basket.py.
prices = {"bread": 2.50, "milk": 1.20, "eggs": 3.00}
print(round(sum(prices.values()), 2))
print(f"Total: {sum(prices.values()):.2f}")
You should see: 6.7 then Total: 6.70. values() hands you just the prices, sum adds them, and the second line is how you show money properly — :.2f forces exactly two decimal places for display.
If not: TypeError: unsupported operand type(s) for +: 'int' and 'str' means one price is text, written with quotes. Prices must be numbers to be added. sum will not convert them for you.
Without scrolling up: you want a price and it might be missing. Which do you use,
prices["x"] or prices.get("x"), and why? Answer:
get — it returns None, or a fallback you choose, instead
of raising KeyError. Use brackets only when a missing key is a bug you
want reported.
Now do it without the page: add a quantities dictionary
with the same three keys, and print the true basket total — price times quantity
for each item. One loop, one running total, the same shape as the control-flow
tutorial.
Summary
- Lists
[]— Ordered, mutable collections. Use for data that changes. - Tuples
()— Ordered, immutable collections. Use for fixed data. - Dictionaries
{}— Key-value pairs. Use when you need to look up values by name. - List comprehensions provide a compact syntax for creating lists
- Nested structures let you model complex real-world data
inchecks membership in all three types
You now have a solid foundation in Python's core data structures. With variables, control flow, functions, and data structures under your belt, you're ready to build real Python programs. Keep practicing!