None & Truthiness
None: Python’s single “nothing” value
Section titled “None: Python’s single “nothing” value”TypeScript has two “absence” values — null and undefined — and a whole linting rule (strictNullChecks) to manage them. Python has one: None. It is both the “no value” sentinel AND what functions return implicitly when they do not return anything explicitly.
You compare against None with is (not ==) — more on that below.
None vs null / undefined
Section titled “None vs null / undefined”// TypeScriptlet user: string | null = null;let config: string | undefined = undefined;
// Nullish coalescingconst name = user ?? "Guest";
// Optional chainingconst len = user?.length ?? 0;
// Type narrowingif (user !== null && user !== undefined) { console.log(user.toUpperCase());}# Pythonuser: str | None = None # str | None = Optional[str]
# Fallback with "or"name = user or "Guest"
# Conditional expression (ternary)length = len(user) if user is not None else 0
# Type narrowingif user is not None: print(user.upper())Truthiness: Python’s falsy values
Section titled “Truthiness: Python’s falsy values”Python’s falsy rules are similar to JavaScript’s but stricter and more consistent. Any empty container is falsy; any non-zero number is truthy.
| Value | Falsy in Python? | Falsy in JS/TS? |
|---|---|---|
None | Yes | null / undefined — Yes |
0 | Yes | Yes |
0.0 | Yes | Yes |
"" (empty string) | Yes | Yes |
[] (empty list) | Yes | No — [] is truthy in JS |
{} (empty dict) | Yes | No — {} is truthy in JS |
set() (empty set) | Yes | N/A |
() (empty tuple) | Yes | N/A |
Notice: empty arrays and objects are truthy in JavaScript but falsy in Python. This catches a lot of TS developers off guard.
// TypeScriptconsole.log(Boolean([])); // true — empty array is truthy!console.log(Boolean({})); // true — empty object is truthy!console.log(Boolean(0)); // falseconsole.log(Boolean("")); // falseconsole.log(Boolean(null)); // false
if ([]) console.log("truthy"); // prints!# Pythonprint(bool([])) # False — empty list is FALSYprint(bool({})) # False — empty dict is FALSYprint(bool(0)) # Falseprint(bool("")) # Falseprint(bool(None)) # False
if []: print("truthy") # does NOT printelse: print("falsy") # prints
# Idiomatic: guard against empty containersitems = []if not items: print("No items found")Checking for None: use is, not ==
Section titled “Checking for None: use is, not ==”In Python, is checks identity (same object in memory). == checks equality (same value). For None, always use is — there is only one None object in the Python process, so identity is the correct check.
// TypeScript — use strict equalityfunction process(data: string | null | undefined): void { if (data === null || data === undefined) { console.log("No data"); return; } console.log(data.toUpperCase());}# Python — use "is None" / "is not None"def process(data: str | None) -> None: if data is None: print("No data") return print(data.upper())
# Common pattern: default if Nonedef greet(name: str | None = None) -> str: name = name or "World" # replaces None (or falsy) with default return f"Hello, {name}!"
print(greet()) # Hello, World!print(greet("Alice")) # Hello, Alice!Try it
Section titled “Try it”# None checksx = Noneprint(x is None) # Trueprint(x is not None) # False
# Truthinessprint(bool([])) # False — empty listprint(bool([1])) # True — non-empty listprint(bool({})) # False — empty dictprint(bool({"a": 1})) # Trueprint(bool("")) # False — empty stringprint(bool("hi")) # Trueprint(bool(0)) # Falseprint(bool(1)) # True
# None in function returndef get_user(user_id: int): if user_id == 1: return {"name": "Alice"} return None # implicit in Python, but explicit is fine
user = get_user(99)if user is None: print("User not found")
user2 = get_user(1)if user2 is not None: print(f"Found: {user2['name']}")Loading Python runtime (first run only)…