Python for Beginners: The Complete Guide to Getting Started
Python is the most popular programming language in the world, and for good reason. Its clean syntax reads like English, it works across every major domain from web development to machine learning, and it has the largest ecosystem of libraries of any language. Whether you want to automate tedious tasks, build web applications, analyze data, or break into the tech industry, Python is the best place to start.
This guide takes you from zero to writing real Python programs. Every section includes code examples you can type and run immediately. By the end, you will understand variables, data types, control flow, functions, file handling, error handling, and how to use Python's enormous library ecosystem.
Table of Contents
1. Why Learn Python
Python consistently ranks as the number one programming language in surveys by TIOBE, Stack Overflow, and GitHub. But popularity alone is not a reason to learn something. Here is why Python deserves that top spot.
Readability
Python was designed to be readable. Compare these snippets that do the same thing — print numbers 1 through 5:
# Python
for i in range(1, 6):
print(i)
// Java
for (int i = 1; i <= 5; i++) {
System.out.println(i);
}
// C
for (int i = 1; i <= 5; i++) {
printf("%d\n", i);
}
Python uses whitespace instead of curly braces, skips semicolons, and reads almost like English. This matters because you spend far more time reading code than writing it.
Use Cases
Python is not limited to one domain. It is genuinely used in production across nearly every area of software:
- Web development — Django, Flask, FastAPI power sites like Instagram, Pinterest, and Mozilla
- Data science and machine learning — pandas, NumPy, scikit-learn, TensorFlow, PyTorch
- Automation and scripting — file processing, web scraping, system administration
- API development — REST and GraphQL APIs with FastAPI, Flask, or Django REST Framework
- DevOps — Ansible, infrastructure tools, CI/CD scripts
- Scientific computing — research, simulations, bioinformatics
- Finance — quantitative analysis, algorithmic trading, risk modeling
- Game development — Pygame, scripting in larger game engines
Job Market
Python developers are among the most in-demand engineers worldwide. The language appears in job listings for backend developers, data engineers, machine learning engineers, DevOps engineers, and full-stack developers. According to industry surveys, Python developers command competitive salaries, and the demand continues to grow as AI and data-driven applications expand across every industry.
2. Installing Python
Before writing any code, you need Python installed on your machine. Here is how to do it on every major platform.
Check If Python Is Already Installed
Open a terminal (or Command Prompt on Windows) and type:
python3 --version
# or on Windows:
python --version
If you see something like Python 3.12.x or Python 3.13.x, you are ready to go. If not, follow the instructions below for your operating system.
Windows
# Option 1: Download from python.org
# Go to https://www.python.org/downloads/
# Download the latest Python 3.x installer
# IMPORTANT: Check "Add Python to PATH" during installation
# Option 2: Install via winget (Windows Package Manager)
winget install Python.Python.3.12
# Option 3: Install via Microsoft Store
# Search "Python 3.12" in the Microsoft Store
# Verify installation
python --version
pip --version
The most common beginner mistake on Windows is forgetting to check "Add Python to PATH" during installation. If you missed it, uninstall and reinstall with that box checked, or manually add Python to your system PATH.
macOS
# macOS comes with Python, but it may be outdated
# Install the latest version with Homebrew
# Install Homebrew if you do not have it
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install Python
brew install python
# Verify
python3 --version
pip3 --version
Linux (Ubuntu/Debian)
# Python 3 is usually pre-installed on modern Linux distributions
python3 --version
# If not installed, or to get the latest version:
sudo apt update
sudo apt install python3 python3-pip python3-venv
# Verify
python3 --version
pip3 --version
Linux (Fedora/RHEL)
sudo dnf install python3 python3-pip
python3 --version
Version Management with pyenv
If you need to work with multiple Python versions (for example, one project requires 3.11 and another requires 3.13), use pyenv:
# Install pyenv (macOS/Linux)
curl https://pyenv.run | bash
# Add to your shell profile (~/.bashrc or ~/.zshrc)
export PATH="$HOME/.pyenv/bin:$PATH"
eval "$(pyenv init -)"
# Install a specific Python version
pyenv install 3.13.1
pyenv install 3.12.8
# Set a global default
pyenv global 3.13.1
# Set a project-specific version
cd my-project
pyenv local 3.12.8 # creates .python-version file
3. Your First Python Program
The Interactive REPL
Python comes with an interactive interpreter called the REPL (Read-Eval-Print Loop). It is perfect for experimenting:
# Start the REPL by typing python3 in your terminal
$ python3
Python 3.13.1 (main, Dec 4 2025, 00:00:00)
>>> 2 + 2
4
>>> "hello" + " " + "world"
'hello world'
>>> len("Python")
6
>>> exit() # or Ctrl+D to quit
The >>> prompt means Python is waiting for your input. Type any expression and Python evaluates it immediately. This is a great way to test small ideas.
Hello, World!
Create a file called hello.py with any text editor:
# hello.py
print("Hello, World!")
Run it from your terminal:
$ python3 hello.py
Hello, World!
That is it. No compilation step, no boilerplate, no class definitions. One line of code and you have a working program.
A Slightly More Interesting Program
# greeting.py
name = input("What is your name? ")
print(f"Hello, {name}! Welcome to Python.")
age = int(input("How old are you? "))
birth_year = 2026 - age
print(f"You were born around {birth_year}.")
$ python3 greeting.py
What is your name? Alice
Hello, Alice! Welcome to Python.
How old are you? 25
You were born around 2001.
This program introduces several concepts: variables, the input() function for reading user input, int() for converting strings to numbers, and f-strings for formatted output. We will cover all of these in detail.
Comments
Comments explain your code to other humans (including your future self). Python ignores them completely:
# This is a single-line comment
# You can put comments above code to explain it
result = 42 * 7 # Or at the end of a line
"""
This is a multi-line string.
Often used as a multi-line comment,
though technically it is a string that
Python evaluates and then discards.
"""
4. Variables and Data Types
Variables are names that refer to values stored in memory. In Python, you do not declare types — Python figures out the type automatically based on the value you assign.
Creating Variables
# No type declarations needed. Just assign a value.
name = "Alice"
age = 30
height = 5.7
is_student = False
# Python determines the type from the value
print(type(name)) # <class 'str'>
print(type(age)) # <class 'int'>
print(type(height)) # <class 'float'>
print(type(is_student)) # <class 'bool'>
Naming Rules
# Valid variable names
user_name = "alice" # snake_case (Python convention)
age2 = 25 # can contain numbers (not at start)
_private = "hidden" # can start with underscore
MAX_SIZE = 100 # ALL_CAPS for constants (by convention)
# Invalid variable names
# 2name = "bob" # cannot start with a number
# my-name = "carol" # hyphens not allowed (use underscores)
# class = "Python" # cannot use reserved keywords
Python convention is snake_case for variables and functions (words separated by underscores, all lowercase). Use ALL_CAPS for constants.
Numbers: int and float
# Integers: whole numbers, no size limit in Python
count = 42
big_number = 1_000_000 # underscores for readability (same as 1000000)
negative = -17
binary = 0b1010 # binary literal = 10
hexadecimal = 0xFF # hex literal = 255
# Floats: decimal numbers
price = 19.99
temperature = -40.0
scientific = 2.5e6 # 2.5 * 10^6 = 2500000.0
# Type conversion
int_from_float = int(3.7) # 3 (truncates, does not round)
float_from_int = float(42) # 42.0
int_from_string = int("123") # 123
float_from_string = float("3.14") # 3.14
Strings
# Strings: sequences of characters
single = 'hello' # single quotes
double = "hello" # double quotes (equivalent)
multiline = """This is
a multiline
string."""
# Strings are immutable: you cannot change individual characters
# but you can create new strings from existing ones
greeting = "Hello" + ", " + "World!" # concatenation
repeated = "ha" * 3 # "hahaha"
Booleans
# Booleans: True or False (note the capital letters)
is_active = True
is_deleted = False
# Booleans result from comparisons
print(5 > 3) # True
print(10 == 20) # False
print("a" != "b") # True
# Truthy and falsy values
# These are falsy (evaluate to False in boolean context):
# False, None, 0, 0.0, "", [], {}, set()
# Everything else is truthy
print(bool(0)) # False
print(bool(42)) # True
print(bool("")) # False
print(bool("hello")) # True
print(bool([])) # False
print(bool([1, 2])) # True
None
# None represents the absence of a value
result = None
print(result) # None
print(type(result)) # <class 'NoneType'>
# Common use: default function arguments, uninitialized state
def find_user(user_id):
# returns None if user not found
return None
user = find_user(999)
if user is None:
print("User not found")
# Always use 'is' and 'is not' to compare with None, never ==
if user is None: # correct
pass
if user is not None: # correct
pass
Multiple Assignment
# Assign multiple variables at once
x, y, z = 1, 2, 3
print(x, y, z) # 1 2 3
# Swap variables (no temp variable needed)
a, b = 10, 20
a, b = b, a
print(a, b) # 20 10
# Same value to multiple variables
x = y = z = 0
5. Operators
Arithmetic Operators
a = 17
b = 5
print(a + b) # 22 addition
print(a - b) # 12 subtraction
print(a * b) # 85 multiplication
print(a / b) # 3.4 division (always returns float)
print(a // b) # 3 floor division (rounds down to int)
print(a % b) # 2 modulo (remainder)
print(a ** b) # 1419857 exponentiation (17^5)
# Floor division and modulo are useful together
minutes = 137
hours = minutes // 60 # 2
remaining = minutes % 60 # 17
print(f"{hours}h {remaining}m") # 2h 17m
Comparison Operators
x = 10
y = 20
print(x == y) # False equal
print(x != y) # True not equal
print(x > y) # False greater than
print(x < y) # True less than
print(x >= 10) # True greater than or equal
print(x <= 5) # False less than or equal
# Chained comparisons (unique to Python)
age = 25
print(18 <= age <= 65) # True (is age between 18 and 65?)
# String comparison (lexicographic/alphabetical)
print("apple" < "banana") # True
print("abc" == "abc") # True
Logical Operators
# and: True if BOTH conditions are True
print(True and True) # True
print(True and False) # False
# or: True if EITHER condition is True
print(True or False) # True
print(False or False) # False
# not: inverts the boolean value
print(not True) # False
print(not False) # True
# Practical example
age = 25
has_license = True
can_drive = age >= 16 and has_license
print(can_drive) # True
# Short-circuit evaluation
# Python stops evaluating as soon as the result is determined
# 'and' stops at the first False, 'or' stops at the first True
result = False and expensive_function() # expensive_function never called
result = True or expensive_function() # expensive_function never called
Assignment Operators
x = 10
x += 5 # x = x + 5 -> 15
x -= 3 # x = x - 3 -> 12
x *= 2 # x = x * 2 -> 24
x /= 4 # x = x / 4 -> 6.0
x //= 2 # x = x // 2 -> 3.0
x **= 3 # x = x ** 3 -> 27.0
x %= 5 # x = x % 5 -> 2.0
# Strings support +=
greeting = "Hello"
greeting += ", World!" # "Hello, World!"
Identity and Membership Operators
# Identity: is, is not (checks if two variables point to the same object)
a = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == b) # True (same value)
print(a is b) # False (different objects in memory)
print(a is c) # True (same object)
# Membership: in, not in (checks if a value exists in a sequence)
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
print("grape" not in fruits) # True
text = "Hello, World!"
print("World" in text) # True
print("world" in text) # False (case-sensitive)
6. Strings
Strings are one of the most used data types in Python. They are sequences of characters and come with dozens of built-in methods. For a complete reference, see our Python String Methods Cheat Sheet.
Creating Strings
# Single or double quotes (identical behavior)
name = 'Alice'
greeting = "Hello, World!"
# Use the other quote type to include quotes in strings
message = "It's a beautiful day"
html = '<div class="container">content</div>'
# Escape characters
newline = "Line 1\nLine 2"
tab = "Column1\tColumn2"
backslash = "C:\\Users\\alice"
# Raw strings (ignore escape characters) - useful for regex and file paths
path = r"C:\Users\alice\documents"
pattern = r"\d+\.\d+"
# Triple quotes for multiline strings
poem = """Roses are red,
Violets are blue,
Python is awesome,
And so are you."""
String Methods
text = " Hello, World! "
# Case methods
print(text.upper()) # " HELLO, WORLD! "
print(text.lower()) # " hello, world! "
print(text.title()) # " Hello, World! "
print(text.capitalize()) # " hello, world! "
print(text.swapcase()) # " hELLO, wORLD! "
# Whitespace
print(text.strip()) # "Hello, World!"
print(text.lstrip()) # "Hello, World! "
print(text.rstrip()) # " Hello, World!"
# Search
print(text.find("World")) # 9 (index of first occurrence)
print(text.find("Python")) # -1 (not found)
print(text.count("l")) # 3
print(text.startswith(" He")) # True
print(text.endswith("! ")) # True
# Replace
print(text.replace("World", "Python")) # " Hello, Python! "
# Split and join
csv_line = "alice,30,engineer"
parts = csv_line.split(",") # ["alice", "30", "engineer"]
print(parts)
words = ["Hello", "World"]
joined = " ".join(words) # "Hello World"
print(joined)
# Check content
print("hello123".isalnum()) # True (alphanumeric)
print("hello".isalpha()) # True (alphabetic only)
print("12345".isdigit()) # True (digits only)
print(" ".isspace()) # True (whitespace only)
F-Strings (Formatted String Literals)
F-strings are the modern way to format strings in Python. They are fast, readable, and powerful:
name = "Alice"
age = 30
height = 5.7
# Basic interpolation
print(f"Name: {name}, Age: {age}")
# Output: Name: Alice, Age: 30
# Expressions inside braces
print(f"Next year: {age + 1}")
# Output: Next year: 31
# Format specifiers
pi = 3.14159265
print(f"Pi: {pi:.2f}") # Pi: 3.14 (2 decimal places)
print(f"Pi: {pi:.4f}") # Pi: 3.1416 (4 decimal places)
price = 49.99
print(f"Price: ${price:,.2f}") # Price: $49.99
big = 1234567890
print(f"Number: {big:,}") # Number: 1,234,567,890
# Padding and alignment
print(f"{'left':<20}|") # "left |"
print(f"{'right':>20}|") # " right|"
print(f"{'center':^20}|") # " center |"
# Useful for tables
items = [("Python", 3.12), ("JavaScript", "ES2024"), ("Rust", 1.75)]
for lang, version in items:
print(f"{lang:<15} {version}")
String Slicing
text = "Python Programming"
# 0123456789...
# Indexing (0-based)
print(text[0]) # "P"
print(text[7]) # "P" (the P in Programming)
print(text[-1]) # "g" (last character)
print(text[-6]) # "m"
# Slicing: [start:stop:step]
print(text[0:6]) # "Python" (start to stop-1)
print(text[7:]) # "Programming" (7 to end)
print(text[:6]) # "Python" (start to 5)
print(text[-11:]) # "Programming"
# Step
print(text[::2]) # "Pto rgamn" (every 2nd character)
print(text[::-1]) # "gnimmargorP nohtyP" (reversed)
# Strings are immutable, so you cannot do text[0] = "p"
# Instead, create a new string
new_text = "p" + text[1:] # "python Programming"
7. Lists and Tuples
Lists
Lists are ordered, mutable collections that can hold items of any type. They are the most commonly used data structure in Python.
# Creating lists
numbers = [1, 2, 3, 4, 5]
fruits = ["apple", "banana", "cherry"]
mixed = [1, "hello", 3.14, True, None]
empty = []
# Nested lists
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
print(matrix[1][2]) # 6 (row 1, column 2)
List Indexing and Slicing
colors = ["red", "green", "blue", "yellow", "purple"]
# Indexing (same as strings)
print(colors[0]) # "red"
print(colors[-1]) # "purple"
# Slicing
print(colors[1:3]) # ["green", "blue"]
print(colors[:3]) # ["red", "green", "blue"]
print(colors[2:]) # ["blue", "yellow", "purple"]
print(colors[::2]) # ["red", "blue", "purple"]
print(colors[::-1]) # ["purple", "yellow", "blue", "green", "red"]
List Methods
fruits = ["apple", "banana"]
# Adding elements
fruits.append("cherry") # ["apple", "banana", "cherry"]
fruits.insert(1, "blueberry") # ["apple", "blueberry", "banana", "cherry"]
fruits.extend(["date", "elderberry"]) # adds multiple items to end
# Removing elements
fruits.remove("banana") # removes first occurrence
popped = fruits.pop() # removes and returns last item
popped = fruits.pop(0) # removes and returns item at index 0
fruits.clear() # removes all items
# Searching
fruits = ["apple", "banana", "cherry", "banana"]
print(fruits.index("banana")) # 1 (first occurrence)
print(fruits.count("banana")) # 2
print("cherry" in fruits) # True
# Sorting
numbers = [3, 1, 4, 1, 5, 9, 2, 6]
numbers.sort() # sorts in place: [1, 1, 2, 3, 4, 5, 6, 9]
numbers.sort(reverse=True) # descending: [9, 6, 5, 4, 3, 2, 1, 1]
# sorted() returns a new list (does not modify original)
original = [3, 1, 4, 1, 5]
new_sorted = sorted(original) # [1, 1, 3, 4, 5]
print(original) # [3, 1, 4, 1, 5] (unchanged)
# Other useful methods
numbers = [1, 2, 3]
numbers.reverse() # [3, 2, 1] (in place)
copy = numbers.copy() # shallow copy
# Length, sum, min, max
nums = [10, 20, 30, 40, 50]
print(len(nums)) # 5
print(sum(nums)) # 150
print(min(nums)) # 10
print(max(nums)) # 50
List Comprehensions
List comprehensions are a concise way to create lists. They are one of Python's most powerful features:
# Traditional way
squares = []
for x in range(10):
squares.append(x ** 2)
# List comprehension (same result, one line)
squares = [x ** 2 for x in range(10)]
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
# With a condition (filter)
even_squares = [x ** 2 for x in range(10) if x % 2 == 0]
# [0, 4, 16, 36, 64]
# Transform strings
names = ["alice", "bob", "charlie"]
upper_names = [name.upper() for name in names]
# ["ALICE", "BOB", "CHARLIE"]
# Flatten a nested list
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [num for row in matrix for num in row]
# [1, 2, 3, 4, 5, 6, 7, 8, 9]
# With if/else (note: different position than filter)
labels = ["even" if x % 2 == 0 else "odd" for x in range(5)]
# ["even", "odd", "even", "odd", "even"]
Tuples
Tuples are like lists but immutable. Once created, you cannot add, remove, or change elements.
# Creating tuples
coordinates = (10, 20)
rgb = (255, 128, 0)
single = (42,) # note the trailing comma for single-element tuples
empty = ()
# Tuples from other iterables
from_list = tuple([1, 2, 3])
from_string = tuple("hello") # ('h', 'e', 'l', 'l', 'o')
# Accessing elements (same as lists)
print(coordinates[0]) # 10
print(rgb[-1]) # 0
# Tuple unpacking
x, y = coordinates
print(x) # 10
print(y) # 20
# Unpacking with * (catch remaining items)
first, *rest = (1, 2, 3, 4, 5)
print(first) # 1
print(rest) # [2, 3, 4, 5]
# Tuples as dictionary keys (lists cannot be used as keys)
locations = {
(40.7128, -74.0060): "New York",
(51.5074, -0.1278): "London",
(35.6762, 139.6503): "Tokyo"
}
print(locations[(40.7128, -74.0060)]) # "New York"
# When to use tuples vs lists:
# - Tuples: fixed data (coordinates, RGB, database rows)
# - Lists: data that changes (shopping cart, user list)
8. Dictionaries and Sets
Dictionaries
Dictionaries store key-value pairs. They are incredibly fast for lookups (O(1) average time) and are one of Python's most important data structures.
# Creating dictionaries
person = {
"name": "Alice",
"age": 30,
"city": "New York",
"languages": ["Python", "JavaScript"]
}
# Empty dictionary
empty = {}
also_empty = dict()
# From list of tuples
pairs = dict([("a", 1), ("b", 2), ("c", 3)])
# dict() with keyword arguments
config = dict(host="localhost", port=8080, debug=True)
Accessing and Modifying
person = {"name": "Alice", "age": 30, "city": "New York"}
# Access values
print(person["name"]) # "Alice"
print(person.get("age")) # 30
print(person.get("email", "N/A")) # "N/A" (default if key not found)
# person["email"] would raise KeyError if key does not exist
# person.get("email") returns None instead (safer)
# Add or update
person["email"] = "alice@example.com" # adds new key
person["age"] = 31 # updates existing key
# Update multiple keys at once
person.update({"age": 32, "job": "engineer"})
# Remove
del person["city"] # removes key (raises KeyError if missing)
email = person.pop("email") # removes and returns value
email = person.pop("email", None) # returns None if missing (safe)
# Check if key exists
if "name" in person:
print(person["name"])
Iterating Over Dictionaries
scores = {"Alice": 95, "Bob": 87, "Charlie": 92}
# Iterate over keys (default)
for name in scores:
print(name)
# Iterate over values
for score in scores.values():
print(score)
# Iterate over key-value pairs
for name, score in scores.items():
print(f"{name}: {score}")
# Dictionary comprehension
squared = {x: x**2 for x in range(6)}
# {0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
# Filter with comprehension
high_scores = {name: score for name, score in scores.items() if score >= 90}
# {"Alice": 95, "Charlie": 92}
# Useful methods
print(list(scores.keys())) # ["Alice", "Bob", "Charlie"]
print(list(scores.values())) # [95, 87, 92]
print(list(scores.items())) # [("Alice", 95), ("Bob", 87), ("Charlie", 92)]
print(len(scores)) # 3
Nested Dictionaries
# Real-world example: API response
users = {
"user_001": {
"name": "Alice",
"email": "alice@example.com",
"roles": ["admin", "editor"]
},
"user_002": {
"name": "Bob",
"email": "bob@example.com",
"roles": ["viewer"]
}
}
# Access nested values
print(users["user_001"]["name"]) # "Alice"
print(users["user_001"]["roles"][0]) # "admin"
# Safe nested access
email = users.get("user_003", {}).get("email", "Not found")
print(email) # "Not found"
Working with nested data structures like JSON is common in Python. Our JSON to Python Converter can help you quickly convert JSON payloads into Python dictionaries and data classes.
Sets
Sets are unordered collections of unique elements. They are perfect for removing duplicates and performing mathematical set operations.
# Creating sets
colors = {"red", "green", "blue"}
numbers = set([1, 2, 3, 2, 1]) # {1, 2, 3} (duplicates removed)
empty_set = set() # NOT {} (that creates an empty dict)
# From a string
letters = set("hello") # {'h', 'e', 'l', 'o'} (duplicates removed)
# Adding and removing
colors.add("yellow")
colors.discard("red") # removes if present (no error if missing)
colors.remove("green") # removes (raises KeyError if missing)
# Set operations
a = {1, 2, 3, 4}
b = {3, 4, 5, 6}
print(a | b) # {1, 2, 3, 4, 5, 6} union
print(a & b) # {3, 4} intersection
print(a - b) # {1, 2} difference (in a but not b)
print(a ^ b) # {1, 2, 5, 6} symmetric difference
# Practical use: remove duplicates from a list
names = ["alice", "bob", "alice", "charlie", "bob"]
unique_names = list(set(names)) # ["alice", "bob", "charlie"]
# Check membership (very fast: O(1))
if "red" in colors:
print("Red is in the set")
# Set comprehension
even = {x for x in range(20) if x % 2 == 0}
# {0, 2, 4, 6, 8, 10, 12, 14, 16, 18}
9. Control Flow
if / elif / else
Conditional statements let your program make decisions:
age = 25
if age < 13:
print("Child")
elif age < 18:
print("Teenager")
elif age < 65:
print("Adult")
else:
print("Senior")
# Output: Adult
Python uses indentation (typically 4 spaces) to define code blocks, not curly braces. This is not optional — incorrect indentation causes an IndentationError.
# Single-line conditional (ternary operator)
status = "adult" if age >= 18 else "minor"
print(status) # "adult"
# Nested conditions
has_ticket = True
is_vip = False
if has_ticket:
if is_vip:
print("Welcome to the VIP section")
else:
print("Welcome! Enjoy the show")
else:
print("Please purchase a ticket")
# Multiple conditions with and/or
temperature = 72
humidity = 45
if temperature > 60 and temperature < 80 and humidity < 60:
print("Perfect weather!")
# Python's chained comparison (cleaner)
if 60 < temperature < 80 and humidity < 60:
print("Perfect weather!")
for Loops
# Iterate over a list
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
print(fruit)
# Iterate over a range
for i in range(5): # 0, 1, 2, 3, 4
print(i)
for i in range(2, 8): # 2, 3, 4, 5, 6, 7
print(i)
for i in range(0, 20, 3): # 0, 3, 6, 9, 12, 15, 18 (step of 3)
print(i)
# Iterate with index using enumerate
fruits = ["apple", "banana", "cherry"]
for index, fruit in enumerate(fruits):
print(f"{index}: {fruit}")
# 0: apple
# 1: banana
# 2: cherry
# Start enumerate from a different number
for index, fruit in enumerate(fruits, start=1):
print(f"{index}. {fruit}")
# 1. apple
# 2. banana
# 3. cherry
# Iterate over a string
for char in "Python":
print(char)
# Iterate over a dictionary
person = {"name": "Alice", "age": 30}
for key, value in person.items():
print(f"{key}: {value}")
# zip: iterate over multiple sequences in parallel
names = ["Alice", "Bob", "Charlie"]
scores = [95, 87, 92]
for name, score in zip(names, scores):
print(f"{name}: {score}")
while Loops
# Basic while loop
count = 0
while count < 5:
print(count)
count += 1
# User input loop
while True:
answer = input("Enter 'quit' to exit: ")
if answer.lower() == "quit":
break
print(f"You entered: {answer}")
# while with else (runs when condition becomes False, not on break)
n = 5
while n > 0:
print(n)
n -= 1
else:
print("Countdown complete!") # This runs
break, continue, and pass
# break: exit the loop immediately
for i in range(100):
if i == 5:
break
print(i)
# Output: 0 1 2 3 4
# continue: skip to the next iteration
for i in range(10):
if i % 2 == 0:
continue # skip even numbers
print(i)
# Output: 1 3 5 7 9
# pass: do nothing (placeholder)
for i in range(5):
pass # TODO: implement this later
# Practical example: find the first negative number
numbers = [4, 7, -2, 9, -5, 3]
for num in numbers:
if num < 0:
print(f"First negative: {num}")
break
# Output: First negative: -2
for...else
# The else block runs if the loop completes without break
numbers = [2, 4, 6, 8]
for num in numbers:
if num % 2 != 0:
print(f"Found odd number: {num}")
break
else:
print("All numbers are even")
# Output: All numbers are even
# Practical use: search with "not found" fallback
target = "grape"
fruits = ["apple", "banana", "cherry"]
for fruit in fruits:
if fruit == target:
print(f"Found {target}!")
break
else:
print(f"{target} not found in list")
10. Functions
Functions are reusable blocks of code that perform a specific task. They are fundamental to writing organized, maintainable programs.
Defining Functions
# Basic function
def greet():
print("Hello, World!")
greet() # call the function
# Function with parameters
def greet_user(name):
print(f"Hello, {name}!")
greet_user("Alice") # Hello, Alice!
# Function with return value
def add(a, b):
return a + b
result = add(3, 5)
print(result) # 8
# Return multiple values (as a tuple)
def get_name_parts(full_name):
parts = full_name.split()
return parts[0], parts[-1]
first, last = get_name_parts("Alice Marie Johnson")
print(first) # Alice
print(last) # Johnson
Default Arguments
# Parameters with default values
def greet(name, greeting="Hello"):
return f"{greeting}, {name}!"
print(greet("Alice")) # Hello, Alice!
print(greet("Bob", "Good morning")) # Good morning, Bob!
# Common pattern: optional configuration
def connect(host, port=5432, timeout=30, ssl=True):
print(f"Connecting to {host}:{port} (timeout={timeout}s, ssl={ssl})")
connect("db.example.com")
connect("db.example.com", port=3306, ssl=False)
# WARNING: Never use mutable default arguments
# Bad:
def add_item(item, items=[]): # this list is shared across all calls!
items.append(item)
return items
# Good:
def add_item(item, items=None):
if items is None:
items = []
items.append(item)
return items
*args and **kwargs
# *args: accept any number of positional arguments
def sum_all(*args):
total = 0
for num in args:
total += num
return total
print(sum_all(1, 2, 3)) # 6
print(sum_all(10, 20, 30, 40)) # 100
# **kwargs: accept any number of keyword arguments
def print_info(**kwargs):
for key, value in kwargs.items():
print(f"{key}: {value}")
print_info(name="Alice", age=30, city="NYC")
# name: Alice
# age: 30
# city: NYC
# Combining all parameter types
def flexible(required, *args, default="hi", **kwargs):
print(f"required: {required}")
print(f"args: {args}")
print(f"default: {default}")
print(f"kwargs: {kwargs}")
flexible("a", "b", "c", default="hey", x=1, y=2)
# required: a
# args: ('b', 'c')
# default: hey
# kwargs: {'x': 1, 'y': 2}
Scope
# Variables defined inside a function are local
def my_function():
local_var = "I'm local"
print(local_var)
my_function()
# print(local_var) # NameError: local_var is not defined
# Variables defined outside functions are global
global_var = "I'm global"
def read_global():
print(global_var) # can read global variables
read_global() # I'm global
# To modify a global variable inside a function, use 'global'
counter = 0
def increment():
global counter
counter += 1
increment()
increment()
print(counter) # 2
# Better approach: avoid global variables, pass and return instead
def increment(counter):
return counter + 1
counter = 0
counter = increment(counter)
counter = increment(counter)
print(counter) # 2
Lambda Functions
Lambda functions are small anonymous functions defined with the lambda keyword:
# Lambda syntax: lambda arguments: expression
square = lambda x: x ** 2
print(square(5)) # 25
add = lambda a, b: a + b
print(add(3, 4)) # 7
# Lambdas are most useful as arguments to other functions
# Sort by custom key
students = [("Alice", 92), ("Bob", 85), ("Charlie", 97)]
students.sort(key=lambda student: student[1])
print(students) # [('Bob', 85), ('Alice', 92), ('Charlie', 97)]
# Filter
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
evens = list(filter(lambda x: x % 2 == 0, numbers))
print(evens) # [2, 4, 6, 8, 10]
# Map
squared = list(map(lambda x: x ** 2, numbers))
print(squared) # [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# Note: list comprehensions are usually preferred over filter/map
evens = [x for x in numbers if x % 2 == 0] # clearer than filter
squared = [x ** 2 for x in numbers] # clearer than map
Docstrings
def calculate_bmi(weight_kg, height_m):
"""
Calculate Body Mass Index (BMI).
Args:
weight_kg: Weight in kilograms.
height_m: Height in meters.
Returns:
BMI value as a float.
Example:
>>> calculate_bmi(70, 1.75)
22.857142857142858
"""
return weight_kg / (height_m ** 2)
# Access the docstring
print(calculate_bmi.__doc__)
help(calculate_bmi)
11. File Handling
Python makes reading and writing files straightforward. The with statement ensures files are properly closed, even if an error occurs.
Reading Files
# Read the entire file at once
with open("example.txt", "r") as file:
content = file.read()
print(content)
# Read line by line (memory-efficient for large files)
with open("example.txt", "r") as file:
for line in file:
print(line.strip()) # strip() removes trailing newline
# Read all lines into a list
with open("example.txt", "r") as file:
lines = file.readlines()
print(lines) # ["line 1\n", "line 2\n", "line 3\n"]
# Read a specific number of characters
with open("example.txt", "r") as file:
first_100_chars = file.read(100)
Writing Files
# Write (creates file or overwrites existing content)
with open("output.txt", "w") as file:
file.write("Hello, World!\n")
file.write("This is line 2.\n")
# Append (adds to existing content)
with open("output.txt", "a") as file:
file.write("This line is appended.\n")
# Write multiple lines
lines = ["Line 1\n", "Line 2\n", "Line 3\n"]
with open("output.txt", "w") as file:
file.writelines(lines)
# Write with print (convenient for formatted output)
with open("output.txt", "w") as file:
print("Name: Alice", file=file)
print("Age: 30", file=file)
print(f"Score: {95.5:.1f}", file=file)
Working with CSV
import csv
# Reading CSV
with open("data.csv", "r") as file:
reader = csv.reader(file)
header = next(reader) # skip header row
for row in reader:
print(row) # each row is a list
# Reading CSV as dictionaries
with open("data.csv", "r") as file:
reader = csv.DictReader(file)
for row in reader:
print(row["name"], row["age"])
# Writing CSV
with open("output.csv", "w", newline="") as file:
writer = csv.writer(file)
writer.writerow(["name", "age", "city"])
writer.writerow(["Alice", 30, "New York"])
writer.writerow(["Bob", 25, "London"])
Working with JSON
import json
# Read JSON file
with open("config.json", "r") as file:
data = json.load(file)
print(data["name"])
# Write JSON file
config = {
"host": "localhost",
"port": 8080,
"debug": True,
"features": ["auth", "logging"]
}
with open("config.json", "w") as file:
json.dump(config, file, indent=2)
# Convert between JSON strings and Python objects
json_string = json.dumps(config, indent=2)
print(json_string)
parsed = json.loads(json_string)
print(parsed["port"]) # 8080
File Path Operations
from pathlib import Path
# Modern way to work with file paths (Python 3.4+)
p = Path("data/reports/2026")
# Create directories
p.mkdir(parents=True, exist_ok=True)
# Check existence
print(Path("example.txt").exists()) # True/False
print(Path("example.txt").is_file()) # True/False
print(Path("data").is_dir()) # True/False
# List files in a directory
for file in Path("data").iterdir():
print(file)
# Find files with patterns
for py_file in Path(".").glob("**/*.py"): # recursive
print(py_file)
# Path components
p = Path("/home/alice/documents/report.pdf")
print(p.name) # "report.pdf"
print(p.stem) # "report"
print(p.suffix) # ".pdf"
print(p.parent) # Path("/home/alice/documents")
# Read and write with Path
content = Path("example.txt").read_text()
Path("output.txt").write_text("Hello, World!")
12. Error Handling
Errors are inevitable. Good Python code anticipates and handles them gracefully instead of crashing.
try / except
# Basic error handling
try:
result = 10 / 0
except ZeroDivisionError:
print("Cannot divide by zero!")
# Handle multiple exception types
try:
number = int(input("Enter a number: "))
result = 100 / number
print(f"Result: {result}")
except ValueError:
print("That's not a valid number!")
except ZeroDivisionError:
print("Cannot divide by zero!")
# Catch multiple exceptions in one block
try:
# some code
pass
except (ValueError, TypeError, KeyError) as e:
print(f"Error: {e}")
try / except / else / finally
try:
file = open("data.txt", "r")
content = file.read()
except FileNotFoundError:
print("File not found!")
content = None
else:
# Runs only if no exception occurred
print(f"File has {len(content)} characters")
finally:
# Always runs, whether exception occurred or not
# Good for cleanup (closing connections, etc.)
print("Operation complete")
# The 'with' statement is preferred for files (handles closing automatically)
try:
with open("data.txt", "r") as file:
content = file.read()
except FileNotFoundError:
print("File not found!")
content = ""
Common Built-in Exceptions
# ValueError: wrong type of value
int("hello") # ValueError: invalid literal for int()
# TypeError: wrong type for an operation
"hello" + 5 # TypeError: can only concatenate str to str
# KeyError: dictionary key not found
d = {"name": "Alice"}
d["age"] # KeyError: 'age'
# IndexError: list index out of range
lst = [1, 2, 3]
lst[10] # IndexError: list index out of range
# FileNotFoundError: file does not exist
open("nonexistent.txt") # FileNotFoundError
# AttributeError: object has no such attribute
"hello".nonexistent() # AttributeError
# NameError: variable not defined
print(undefined_var) # NameError: name 'undefined_var' is not defined
# ImportError: module not found
import nonexistent_module # ModuleNotFoundError
Raising Exceptions
# Raise an exception when something is wrong
def set_age(age):
if age < 0:
raise ValueError("Age cannot be negative")
if age > 150:
raise ValueError("Age seems unrealistic")
return age
try:
set_age(-5)
except ValueError as e:
print(f"Invalid age: {e}") # Invalid age: Age cannot be negative
# Re-raise an exception after logging/handling
try:
result = risky_operation()
except Exception as e:
print(f"Error occurred: {e}")
raise # re-raises the same exception
Custom Exceptions
# Define custom exceptions for your application
class InsufficientFundsError(Exception):
def __init__(self, balance, amount):
self.balance = balance
self.amount = amount
super().__init__(
f"Cannot withdraw ${amount:.2f}. "
f"Balance is ${balance:.2f}."
)
class BankAccount:
def __init__(self, balance):
self.balance = balance
def withdraw(self, amount):
if amount > self.balance:
raise InsufficientFundsError(self.balance, amount)
self.balance -= amount
return self.balance
# Usage
account = BankAccount(100.00)
try:
account.withdraw(150.00)
except InsufficientFundsError as e:
print(e) # Cannot withdraw $150.00. Balance is $100.00.
print(f"Short by: ${e.amount - e.balance:.2f}") # Short by: $50.00
13. Modules and Packages
Python's real power comes from its enormous ecosystem of modules and packages. The standard library alone has hundreds of modules, and PyPI (Python Package Index) hosts over 500,000 third-party packages.
Importing Modules
# Import the entire module
import math
print(math.pi) # 3.141592653589793
print(math.sqrt(16)) # 4.0
# Import specific items
from math import pi, sqrt
print(pi) # 3.141592653589793
print(sqrt(16)) # 4.0
# Import with an alias
import datetime as dt
today = dt.date.today()
print(today) # 2026-02-11
# Import everything (avoid this - pollutes namespace)
from math import * # not recommended in production code
Useful Standard Library Modules
import os
import sys
import datetime
import random
import re
import collections
# os: operating system interface
print(os.getcwd()) # current working directory
print(os.listdir(".")) # list directory contents
os.makedirs("new/path", exist_ok=True)
# sys: system-specific parameters
print(sys.version) # Python version
print(sys.platform) # "linux", "darwin", "win32"
# sys.argv # command-line arguments
# datetime: date and time
now = datetime.datetime.now()
print(now.strftime("%Y-%m-%d %H:%M:%S")) # 2026-02-11 14:30:00
birthday = datetime.date(1995, 6, 15)
age_days = (datetime.date.today() - birthday).days
print(f"Days alive: {age_days}")
# random: random number generation
print(random.randint(1, 100)) # random int between 1 and 100
print(random.choice(["a", "b", "c"])) # random item from list
print(random.random()) # random float 0.0 to 1.0
items = [1, 2, 3, 4, 5]
random.shuffle(items) # shuffles list in place
print(items)
# re: regular expressions
text = "Call me at 555-1234 or 555-5678"
phones = re.findall(r"\d{3}-\d{4}", text)
print(phones) # ["555-1234", "555-5678"]
# collections: specialized containers
from collections import Counter, defaultdict
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
count = Counter(words)
print(count) # Counter({"apple": 3, "banana": 2, "cherry": 1})
print(count.most_common(2)) # [("apple", 3), ("banana", 2)]
# defaultdict: dict with default values for missing keys
word_lengths = defaultdict(list)
for word in ["hi", "hello", "hey", "world", "cat"]:
word_lengths[len(word)].append(word)
print(dict(word_lengths))
# {2: ["hi"], 5: ["hello", "world"], 3: ["hey", "cat"]}
Installing Third-Party Packages with pip
# pip is Python's package manager
pip install requests # HTTP library
pip install flask # web framework
pip install pandas # data analysis
pip install numpy # numerical computing
# Install a specific version
pip install requests==2.31.0
# Install from a requirements file
pip install -r requirements.txt
# List installed packages
pip list
# Show info about a package
pip show requests
# Uninstall
pip uninstall requests
# Create a requirements file from current environment
pip freeze > requirements.txt
Virtual Environments
Virtual environments isolate project dependencies so different projects can use different package versions without conflicts. Always use virtual environments.
# Create a virtual environment
python3 -m venv myproject_env
# Activate it
# Linux/macOS:
source myproject_env/bin/activate
# Windows:
myproject_env\Scripts\activate
# Your prompt changes to show the active environment:
(myproject_env) $ pip install requests
(myproject_env) $ pip install flask
# Packages are installed only in this environment
(myproject_env) $ pip list
# shows only packages in this environment
# Save dependencies
(myproject_env) $ pip freeze > requirements.txt
# Deactivate when done
(myproject_env) $ deactivate
# Another developer can recreate your environment:
python3 -m venv env
source env/bin/activate
pip install -r requirements.txt
Creating Your Own Modules
# utils.py - your own module
def celsius_to_fahrenheit(celsius):
"""Convert Celsius to Fahrenheit."""
return celsius * 9/5 + 32
def fahrenheit_to_celsius(fahrenheit):
"""Convert Fahrenheit to Celsius."""
return (fahrenheit - 32) * 5/9
PI = 3.14159
# main.py - import your module
import utils
print(utils.celsius_to_fahrenheit(100)) # 212.0
print(utils.PI) # 3.14159
# Or import specific functions
from utils import celsius_to_fahrenheit
print(celsius_to_fahrenheit(0)) # 32.0
The if __name__ == "__main__" Pattern
# utils.py
def add(a, b):
return a + b
def multiply(a, b):
return a * b
# This block only runs when utils.py is executed directly,
# NOT when it is imported by another module
if __name__ == "__main__":
# Test our functions
print(add(2, 3)) # 5
print(multiply(4, 5)) # 20
print("All tests passed!")
# When imported: import utils -> only the functions are available
# When run directly: python3 utils.py -> the test code runs too
14. Next Steps
You now have a solid foundation in Python. The next step depends on what you want to build. Here are the most popular paths and the libraries you need for each.
Web Development
# Flask: lightweight web framework (great for beginners)
pip install flask
# app.py
from flask import Flask
app = Flask(__name__)
@app.route("/")
def home():
return "Hello, World!"
@app.route("/greet/<name>")
def greet(name):
return f"Hello, {name}!"
if __name__ == "__main__":
app.run(debug=True)
# Run: python3 app.py
# Visit: http://localhost:5000
# Also explore:
# - Django: full-featured framework (admin panel, ORM, auth built-in)
# - FastAPI: modern, fast, automatic API documentation
Data Science and Analysis
# Essential data science stack
pip install pandas numpy matplotlib
import pandas as pd
import numpy as np
# Load and analyze data
df = pd.read_csv("sales.csv")
print(df.head()) # first 5 rows
print(df.describe()) # statistical summary
print(df.groupby("region")["revenue"].sum())
# NumPy for numerical operations
arr = np.array([1, 2, 3, 4, 5])
print(arr.mean()) # 3.0
print(arr.std()) # 1.4142135623730951
# Also explore:
# - scikit-learn: machine learning
# - TensorFlow / PyTorch: deep learning
# - Jupyter notebooks: interactive data exploration
Automation and Scripting
# Automate file processing
import os
from pathlib import Path
# Rename files in bulk
for file in Path("photos").glob("*.jpg"):
new_name = file.stem.lower().replace(" ", "-") + file.suffix
file.rename(file.parent / new_name)
# Web scraping
pip install requests beautifulsoup4
import requests
from bs4 import BeautifulSoup
response = requests.get("https://example.com")
soup = BeautifulSoup(response.text, "html.parser")
titles = [h2.text for h2 in soup.find_all("h2")]
print(titles)
# Also explore:
# - selenium: browser automation
# - schedule: task scheduling
# - paramiko: SSH automation
Practice Resources
- Build projects — a to-do app, a web scraper, a CLI tool, a personal budget tracker
- Coding challenges — LeetCode, HackerRank, Codewars, Project Euler
- Read other people's code — explore GitHub repositories of Python projects you use
- Official Python documentation — docs.python.org is comprehensive and well-written
- Contribute to open source — find beginner-friendly issues on GitHub
The best way to learn Python is to write Python. Pick a project that interests you and start building. You will encounter problems, search for solutions, and learn far more than any tutorial can teach you.
Frequently Asked Questions
Is Python a good first programming language?
Python is widely considered the best first programming language. Its syntax reads like English, it does not require semicolons or curly braces for code blocks, and it enforces clean indentation. Python also has an enormous ecosystem of libraries, a welcoming community, and is used in nearly every domain from web development to artificial intelligence. Universities worldwide have adopted Python as their introductory programming language, replacing Java and C++.
Should I learn Python 2 or Python 3?
Always learn Python 3. Python 2 reached its official end of life on January 1, 2020, and no longer receives security updates. All modern libraries, frameworks, and tutorials target Python 3. As of 2026, Python 3.12 and 3.13 are the current stable releases. There is no reason to learn Python 2 unless you are maintaining legacy code, and even then you should be migrating to Python 3.
How long does it take to learn Python?
You can learn the basics of Python (variables, loops, functions, and simple file operations) in 2-4 weeks of consistent daily practice. Becoming comfortable enough to build small projects typically takes 2-3 months. Reaching an intermediate level where you can work with libraries, APIs, and build complete applications usually takes 6-12 months. Mastery is an ongoing process that depends on your domain (web development, data science, automation) and the depth of your practice.
What can I build with Python?
Python is used across nearly every domain in software: web applications (Django, Flask, FastAPI), data science and machine learning (pandas, scikit-learn, TensorFlow, PyTorch), automation and scripting (file processing, web scraping, system administration), API development, desktop applications (Tkinter, PyQt), game development (Pygame), DevOps tools, scientific computing (NumPy, SciPy), and more. Companies like Google, Instagram, Spotify, Netflix, and Dropbox use Python extensively in their technology stacks.
Do I need to be good at math to learn Python?
No. Basic arithmetic (addition, subtraction, multiplication, division) is sufficient for the vast majority of Python programming. You do not need advanced math to build web applications, write automation scripts, process files, or work with APIs. Math becomes more relevant only in specialized fields like data science, machine learning, and scientific computing. Even in those fields, Python libraries handle the complex math for you. Do not let math anxiety stop you from learning to code.
What is the difference between a Python list and a tuple?
Lists and tuples both store ordered sequences of items, but they differ in mutability. Lists are mutable: you can add, remove, and change elements after creation using methods like append(), remove(), and index assignment. Tuples are immutable: once created, their contents cannot be changed. Use lists when your data needs to change (a shopping cart, a list of users) and tuples when it should remain constant (coordinates, RGB colors, database records). Tuples are slightly faster than lists and can be used as dictionary keys, while lists cannot.
Learn More
- Python String Methods Cheat Sheet — quick reference for every Python string method with examples
- JSON to Python Converter — convert JSON API responses to Python dictionaries and data classes instantly
- Python Formatter — format and beautify your Python code online
- Regex Cheat Sheet — regular expression patterns for Python's
remodule - Docker Containers for Beginners — learn to containerize your Python applications for deployment