Introduction to Python: Readable, Powerful, Everywhere
Why Python
Guido van Rossum started Python in 1989 as a hobby project over Christmas break. He wanted a language that was easy to read, easy to teach, and powerful enough to get real work done. He named it after Monty Python. Thirty-five years later, it is the most widely taught programming language in the world and the backbone of the artificial intelligence revolution.
Python’s design philosophy is captured in a document called The Zen of Python. You can read it by typing import this in a Python interpreter. The most important lines:
“Readability counts.”
“Simple is better than complex. Complex is better than complicated.”
Python achieves readability through significant whitespace (indentation is syntax), minimal punctuation (no semicolons, no braces for blocks), and a standard library so comprehensive it is described as “batteries included.” The result is a language where a beginner can write useful programs on day one and an expert can build production systems without fighting the language.
I. Hello, World
That is the entire program. No imports, no main function, no class wrapper, no semicolons. Save it as hello.py and run it:
Or use the interactive REPL:
The REPL (Read-Eval-Print Loop) is one of Python’s best features for learning and experimentation. Type an expression, see the result immediately. No compilation step, no boilerplate. This instant feedback loop is why Python is the most popular first language in computer science education.
II. Variables and Types
Python is dynamically typed. You do not declare types; the interpreter infers them at runtime.
Python follows “duck typing”: if it walks like a duck and quacks like a duck, it is a duck. The interpreter does not care what type a variable is. It cares whether the variable supports the operation you are performing on it. Call .upper() on anything that has an upper method; it does not matter whether it is a str or a custom class.
Numeric Types
Python integers never overflow. They grow to arbitrary size. This is unusual among programming languages and means you never need to worry about integer overflow bugs. The tradeoff is performance: big-integer arithmetic is slower than fixed-width integers in C or Go.
III. Strings
f-strings are Python’s best feature for string formatting. They are readable, fast, and support arbitrary expressions inside the braces. Before f-strings, Python had % formatting and .format(); both still work, but f-strings are superior in almost every case.
IV. Data Structures
Lists
Python lists are dynamic arrays (like Java’s ArrayList or Go’s slices). They are ordered, mutable, and can hold mixed types (though you usually keep them homogeneous).
Tuples
Tuples are immutable lists. Use them when the data should not change: coordinates, return values, dictionary keys.
Dictionaries
Dictionaries are hash maps. They are Python’s most important data structure after lists.
Sets
V. Control Flow
The for/else Clause
This is unusual. Python’s for loop has an optional else clause that runs only if the loop completed without hitting a break.
Match/Case (Python 3.10+)
Python’s match is more powerful than a switch statement. It does structural pattern matching: you can match on types, destructure sequences and dictionaries, and bind variables in the match arms.
VI. Functions
Docstrings
Docstrings are the first string literal in a function, class, or module. They become the __doc__ attribute and are used by help() and documentation generators. Use them.
VII. Comprehensions and Generators
Comprehensions are Python’s most elegant feature. They replace explicit loops with concise, readable expressions.
Generators
Generators produce values lazily, one at a time, without building the entire list in memory. Use them when the sequence is large or infinite.
The difference matters when the data is large. A list comprehension [x**2 for x in range(10_000_000)] allocates a list of ten million integers. A generator expression (x**2 for x in range(10_000_000)) produces them one at a time, using constant memory.
VIII. Decorators
A decorator is a function that takes a function and returns a modified version of it. The @ syntax is syntactic sugar for wrapping a function at definition time.
Built-in Decorators
IX. Classes
The __dunder__ methods (double underscore, or “dunder” methods) let you define how your objects behave with built-in operations. __repr__ controls what print() shows. __add__ controls the + operator. __len__ controls len(). __getitem__ controls [] indexing. This is how Python achieves operator overloading.
Dataclasses
For simple data-holding classes, @dataclass eliminates boilerplate:
Inheritance
X. Error Handling
Context Managers (the with Statement)
The with statement is Python’s equivalent of Go’s defer or Java’s try-with-resources. It guarantees that resources (files, database connections, locks) are properly cleaned up. Always use with for files. Never use f = open(...) without it.
XI. Modules and Packages
Virtual Environments
Always use virtual environments. Never install packages into the system Python. This isolates project dependencies and prevents version conflicts. Every Python project should have its own virtual environment.
XII. The Standard Library
| Module | What It Does |
|---|---|
| os, sys | OS interaction, environment variables, command-line args, file paths |
| pathlib | Modern path manipulation (prefer over os.path) |
| json | JSON encoding/decoding. json.dumps(), json.loads() |
| collections | Counter, defaultdict, deque, namedtuple, OrderedDict |
| itertools | chain, product, permutations, combinations, islice, groupby |
| functools | lru_cache, reduce, partial, wraps |
| re | Regular expressions. re.search(), re.findall(), re.sub() |
| datetime | Dates, times, timezones, formatting, arithmetic |
| typing | Type hints: List, Dict, Optional, Union, Callable, TypeVar |
| unittest, pytest | Testing frameworks (pytest is third-party but universal) |
| logging | Structured logging with levels, handlers, formatters |
| http.server | Simple HTTP server in one line: python3 -m http.server |
| sqlite3 | Built-in SQLite database interface |
| argparse | Command-line argument parsing |
| csv | CSV file reading and writing |
| math, statistics | Mathematical functions, basic statistics |
collections.Counter
XIII. Python for Data
Python dominates data science and machine learning because of four libraries:
| Library | What It Does |
|---|---|
| NumPy | N-dimensional arrays and vectorized math. The foundation of everything below. C performance with Python syntax. |
| pandas | DataFrames: labeled, indexed, SQL-like tables. read_csv, groupby, merge, pivot. The workhorse of data analysis. |
| matplotlib / seaborn | Plotting: line charts, scatter plots, histograms, heatmaps. Publication-quality figures. |
| scikit-learn | Machine learning: regression, classification, clustering, preprocessing, model selection. Consistent API for everything. |
The AI revolution runs on Python. GPT, DALL-E, Stable Diffusion, AlphaFold — all trained using PyTorch or TensorFlow, both of which have Python as their primary interface. If you want to work in machine learning, you will work in Python. There is no serious alternative.
XIV. Putting It Together
Here is a complete program that demonstrates comprehensions, generators, dictionaries, Counter, error handling, context managers, and formatted output. It reads a text file, counts word frequencies, and reports the results.
What Python Trades Away
| What You Lose | What You Get |
|---|---|
| Speed (10–100x slower than C) | Development speed (write programs in hours, not days) |
| Static type checking | Flexibility, rapid prototyping, duck typing |
| Compiled binaries | Instant edit-run cycle, no compilation step |
| Low-level memory control | Automatic garbage collection, no segfaults |
| True parallelism (the GIL) | Simple concurrency model, multiprocessing as alternative |
The Global Interpreter Lock (GIL) means only one thread can execute Python bytecode at a time. This makes CPU-bound multithreading useless in Python. For CPU-bound parallelism, use the multiprocessing module or write the hot loop in C/Rust. For I/O-bound concurrency (web requests, file I/O), threads and asyncio work fine because the GIL is released during I/O operations.
Python is slow. This is not a secret. But for most applications, it does not matter. If your program spends 90% of its time waiting for network responses, database queries, or user input, the speed of the language is irrelevant. And when performance does matter, Python calls into C: NumPy, pandas, PyTorch, and most performance-critical libraries are written in C or C++ with Python bindings. You get C speed with Python syntax.
Summary
Python is not trying to be the fastest language, or the most type-safe, or the most elegant. It is trying to be the most useful language for the widest range of people and problems. Its design can be summarized in a few principles:
- Readability is not optional. Indentation is syntax. There is one obvious way to do things. Code is read more often than it is written.
- Batteries included. The standard library handles JSON, HTTP, databases, regex, CSV, dates, logging, and testing without external dependencies.
- Duck typing. If it works, it works. The type system gets out of your way. Type hints exist for documentation and tooling, not enforcement.
- Rapid prototyping. The REPL, dynamic typing, and minimal boilerplate mean you can go from idea to working code in minutes.
- Ecosystem. PyPI has over 500,000 packages. Whatever you need to build — a web app, a data pipeline, a machine learning model, a CLI tool, a game, a script to rename 10,000 files — someone has already built a library for it.
Python is the language you learn in a weekend and use for a career. It is the language of AI research, data science, web backends, DevOps automation, scientific computing, and introductory computer science courses. It is not the right tool for every job. But it is the right first tool for almost every programmer, and the right only tool for a surprising number of problems.