Python for Beginners: The Complete Guide to Getting Started

Published February 11, 2026 · 40 min read

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.

⚙ Quick reference: Keep our Python String Methods Cheat Sheet open while reading — it covers every string method mentioned here in a scannable format.

Table of Contents

  1. Why Learn Python
  2. Installing Python
  3. Your First Python Program
  4. Variables and Data Types
  5. Operators
  6. Strings
  7. Lists and Tuples
  8. Dictionaries and Sets
  9. Control Flow
  10. Functions
  11. File Handling
  12. Error Handling
  13. Modules and Packages
  14. Next Steps
  15. Frequently Asked Questions

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:

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

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.

⚙ Essential tools: Convert API responses with our JSON to Python Converter, format your code with the Python Formatter, and reference string methods with our Python String Methods Cheat Sheet.

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

Related Resources

Python String Methods Cheat Sheet
Complete reference for Python string methods
JSON to Python Converter
Convert JSON to Python dictionaries and data classes
Python Formatter
Format and beautify Python code online
Regex Cheat Sheet
Regular expression patterns for Python's re module
JSON Formatter
Format and validate JSON data for Python development
Docker for Beginners
Containerize your Python apps for deployment