Python Basics — The Complete Notebook
Comprehensive guide on Python Basics — The Complete Notebook.
Python Basics
1. Overview#
Python is a dynamically typed, interpreted, high-level language built around readability. This note covers the true foundation: how Python stores values, how it makes decisions, and how it repeats work. Everything else in the language — OOP, decorators, async — is built on top of these core mechanics.
Everything in Python is an object, including integers, functions, and modules. Each object carries a reference count, a type descriptor, and a value in memory.
2. The Type System#
2.1 Built-in Data Types#
| Type | Example | Mutable? |
|---|---|---|
int | 42 | No |
float | 3.14 | No |
str | "hello" | No |
bool | True, False | No |
NoneType | None | N/A |
list | [1, 2, 3] | Yes |
tuple | (1, 2, 3) | No |
dict | {"a": 1} | Yes |
set | {1, 2, 3} | Yes |
2.2 Dynamic Typing#
Python doesn't require declaring a variable's type — the type is attached to the value, not the variable name.
🐍 PythonInteractive WebAssemblyx = 10 # x refers to an int
x = "ten" # now x refers to a str — completely legal
print(type(x)) # <class 'str'>
2.3 Type Checking#
🐍 PythonInteractive WebAssemblyvalue = 42
print(type(value) == int) # Works, but fragile with subclasses
print(isinstance(value, int)) # Preferred — respects inheritance
2.4 Type Conversion (Casting)#
🐍 PythonInteractive WebAssemblyage_str = "25"
age_int = int(age_str) # "25" -> 25
price = float("19.99") # "19.99" -> 19.99
flag = bool(0) # 0 -> False (falsy)
items = list("abc") # "abc" -> ['a', 'b', 'c']
Falsy values in Python:
0,0.0,"",[],{},(),set(),None,False. Everything else is truthy.
3. Memory Model: Mutability vs Immutability#
| Category | Data Types | Memory Behavior |
|---|---|---|
| Immutable | int, float, str, tuple, frozenset, bytes | Values cannot be modified in-place; changes allocate a new object. |
| Mutable | list, dict, set, bytearray | Values can be modified in-place without changing memory address (id). |
🐍 PythonInteractive WebAssembly# Immutable strings
text = "hello"
print(id(text))
text += " world"
print(id(text)) # New memory location!
# Mutable lists
data_points = [10, 20, 30]
print(id(data_points))
data_points.append(40)
print(id(data_points)) # Same memory location
4. Operators#
4.1 Arithmetic & Comparison#
🐍 PythonInteractive WebAssemblya, b = 17, 5
print(a // b) # 3 — floor division
print(a % b) # 2 — modulo
print(a ** b) # 1419857 — exponentiation
print(a != b) # True
4.2 Logical Operators#
🐍 PythonInteractive WebAssemblyage = 25
has_id = True
print(age >= 18 and has_id) # True
print(age < 18 or has_id) # True
print(not has_id) # False
4.3 Identity vs Equality#
🐍 PythonInteractive WebAssemblya = [1, 2, 3]
b = [1, 2, 3]
c = a
print(a == c) # True — same value
print(a is c) # True — same object
print(a == b) # True — same value
print(a is b) # False — different objects in memory
4.4 The Walrus Operator (:=)#
Introduced in Python 3.8 — assigns and returns a value in the same expression, reducing repeated computation.
🐍 PythonInteractive WebAssemblydata = [1, 2, 3, 4, 5, 6, 7, 8]
# Without walrus
n = len(data)
if n > 5:
print(f"List is long: {n} items")
# With walrus
if (n := len(data)) > 5:
print(f"List is long: {n} items")
5. Control Flow#
5.1 Conditionals#
🐍 PythonInteractive WebAssemblyscore = 82
if score >= 90:
grade = "A"
elif score >= 75:
grade = "B"
elif score >= 60:
grade = "C"
else:
grade = "F"
print(grade) # B
5.2 for Loops & range#
🐍 PythonInteractive WebAssemblyfor i in range(0, 10, 2): # start, stop, step
print(i) # 0, 2, 4, 6, 8
for index, name in enumerate(["Asha", "Ravi", "Meera"]):
print(index, name)
5.3 while Loops#
🐍 PythonInteractive WebAssemblyattempts = 0
while attempts < 3:
print(f"Attempt {attempts + 1}")
attempts += 1
5.4 break, continue, and the Loop else#
The else block on a loop runs only if the loop completes without hitting break — useful for search patterns.
🐍 PythonInteractive WebAssemblynumbers = [4, 8, 15, 16, 23, 42]
target = 99
for n in numbers:
if n == target:
print("Found it!")
break
else:
print("Target not found") # This runs, since break never triggered
6. Core Data Structures#
6.1 Lists — Ordered, Mutable#
🐍 PythonInteractive WebAssemblyfruits = ["apple", "banana", "cherry"]
fruits.append("date")
fruits.insert(1, "avocado")
fruits.remove("banana")
print(fruits[-1]) # date — negative indexing
print(fruits[1:3]) # slicing
6.2 Tuples — Ordered, Immutable#
🐍 PythonInteractive WebAssemblycoordinates = (12.9716, 77.5946) # lat, long
lat, long = coordinates # unpacking
print(f"Lat: {lat}, Long: {long}")
6.3 Dictionaries — Key-Value Pairs#
🐍 PythonInteractive WebAssemblyuser = {"name": "Kamal", "role": "Engineer"}
user["company"] = "Hyperthink Systems" # add new key
print(user.get("email", "Not provided")) # safe access with default
for key, value in user.items():
print(f"{key}: {value}")
6.4 Sets — Unique, Unordered#
🐍 PythonInteractive WebAssemblytags_a = {"python", "ai", "backend"}
tags_b = {"python", "ml", "frontend"}
print(tags_a & tags_b) # intersection: {'python'}
print(tags_a | tags_b) # union
print(tags_a - tags_b) # difference: {'ai', 'backend'}
7. String Formatting#
🐍 PythonInteractive WebAssemblyname = "Kamal"
score = 95.5
# f-strings (preferred, Python 3.6+)
print(f"{name} scored {score:.1f}%")
# .format() method
print("{} scored {:.1f}%".format(name, score))
# % formatting (legacy, still seen in older code)
print("%s scored %.1f%%" % (name, score))
7.1 Useful f-string Tricks#
🐍 PythonInteractive WebAssemblyvalue = 3.14159265
print(f"{value:.2f}") # 3.14 — 2 decimal places
print(f"{1000000:,}") # 1,000,000 — thousands separator
print(f"{'text':>10}") # right-align within 10 chars
print(f"{value=}") # value=3.14159265 — debug-friendly, Python 3.8+
8. Idiomatic Python Patterns#
8.1 List & Dict Comprehensions#
Comprehensions run at C-level speed inside the interpreter, making them faster and more readable than manual loops.
🐍 PythonInteractive WebAssemblyraw_scores = [45, 88, 92, 31, 78, 99, 100]
high_scores = [score for score in raw_scores if score >= 80]
feature_names = ["age", "income", "credit_score"]
feature_idx_map = {name: idx for idx, name in enumerate(feature_names)}
8.2 Context Managers (with statement)#
Ensures deterministic resource cleanup (files, DB connections, locks).
🐍 PythonInteractive WebAssemblyclass ModelArtifactManager:
def __init__(self, filepath):
self.filepath = filepath
def __enter__(self):
self.file = open(self.filepath, "w")
return self.file
def __exit__(self, exc_type, exc_val, exc_tb):
self.file.close()
return False
9. Common Pitfalls#
INCORRECT: Mutable Default Arguments#
🐍 PythonInteractive WebAssemblydef append_prediction(val, container=[]):
container.append(val)
return container
print(append_prediction(1)) # [1]
print(append_prediction(2)) # [1, 2] -> shared across calls!
CORRECT: Fix#
🐍 PythonInteractive WebAssemblydef append_prediction(val, container=None):
if container is None:
container = []
container.append(val)
return container
INCORRECT: Modifying a List While Iterating#
🐍 PythonInteractive WebAssemblynums = [1, 2, 3, 4, 5]
for n in nums:
if n % 2 == 0:
nums.remove(n) # skips elements — unpredictable results
CORRECT: Fix#
🐍 PythonInteractive WebAssemblynums = [1, 2, 3, 4, 5]
nums = [n for n in nums if n % 2 != 0]
10. Summary & Best Practices Checklist#
- Use
isfor identity/Nonechecks,==for value equality. - Prefer f-strings for readability and performance.
- Never use a mutable object (
list,dict) as a default argument. - Use
enumerate()instead of manual index counters. - Use comprehensions for simple transforms; fall back to loops when logic gets complex.
- Use
dict.get()with a default instead of risking aKeyError. - Reach for tuples when data shouldn't change (e.g., coordinates, RGB values).
Python Memory Model & Fundamentals Checkpoint
Finished studying this notebook?
Mark this guide as completed to update your course progress roadmap.