Python Keywords and Identifiers Explained — Rules, Reserved Words and Real Mistakes
Every language has a vocabulary. English has words like 'the', 'is', and 'if' that carry fixed grammatical meaning — you can't just decide 'if' now means a type of sandwich. Python works the same way. It has a built-in vocabulary of reserved words that power every program ever written in the language, and the moment you open a Python file, those rules are already in force whether you know about them or not. Understanding them isn't optional trivia — it's the foundation everything else is built on.
The problem most beginners hit is that Python's error messages when you misuse keywords are genuinely confusing at first. You try to name a variable 'list' or 'print' and something breaks in a way that doesn't obviously point to a naming problem. Knowing the rules up front means you spend your time actually building things rather than puzzling over cryptic SyntaxError messages at 11 pm.
By the end of this article you'll know every Python keyword by category, you'll be able to write identifiers that are both legal and professional, you'll understand exactly why Python enforces these rules, and you'll be able to spot and fix the three most common beginner naming mistakes on sight. Let's build this up from zero.
What Python Keywords Actually Are — and Why You Can't Touch Them
A Python keyword is a word that is permanently reserved by the language itself. Python's interpreter reads your code word by word, and when it hits a keyword, it doesn't ask what you meant — it already knows. Keywords are the grammar of Python. They're the skeleton that holds every statement together.
Python 3 currently has 35 keywords. Every single one of them serves a specific structural purpose. 'if' starts a condition. 'for' starts a loop. 'def' starts a function. 'True' and 'False' are the only two boolean values. 'None' represents the absence of a value. None of these can be reassigned, overwritten, or used as variable names.
You can see the complete list at any time by running two lines of Python. The 'keyword' module is part of Python's standard library — it ships with Python, no installation needed — and 'keyword.kwlist' gives you the full list in alphabetical order. This is worth memorising not because an interviewer will quiz you on all 35, but because recognising them on sight stops you accidentally walking into a naming collision.
Notice that all 35 keywords are lowercase except 'True', 'False', and 'None'. That capitalisation isn't a style choice — it's part of the specification. Python is case-sensitive, so 'true' (all lowercase) is not a keyword and can technically be used as a variable name, though doing so is a terrible idea for readability.
import keyword # Python's built-in keyword module — no install needed # Get the full list of all reserved keywords in your Python version all_keywords = keyword.kwlist print(f"Python {__import__('sys').version.split()[0]} has {len(all_keywords)} keywords:\n") # Print keywords in rows of 5 so they're easy to read for index, word in enumerate(all_keywords): # end='' prevents a newline after each word; we add our own spacing print(f"{word:<12}", end='') # After every 5th keyword, drop to a new line if (index + 1) % 5 == 0: print() # moves the cursor to the next line print() # final newline for clean terminal output # Check whether a specific word is a keyword — returns True or False word_to_check = "while" print(f"\nIs '{word_to_check}' a Python keyword? {keyword.iskeyword(word_to_check)}") word_to_check = "speed" print(f"Is '{word_to_check}' a Python keyword? {keyword.iskeyword(word_to_check)}")
False None True and as
assert async await break class
continue def del elif else
except finally for from global
if import in is lambda
nonlocal not or pass raise
return try while with yield
Is 'while' a Python keyword? True
Is 'speed' a Python keyword? False
Python Identifiers — The Naming Rules You Must Know Cold
An identifier is any name you create yourself — variable names, function names, class names, module names. You have freedom here, but Python enforces a firm set of rules. Break any one of them and you get a SyntaxError before your code even runs.
The rules are: (1) An identifier can only contain letters (a–z, A–Z), digits (0–9), and underscores (_). (2) It must not start with a digit — 'player1' is legal, '1player' is not. (3) It must not be a keyword. (4) It cannot contain spaces or special characters like @, $, %, !, or hyphens.
Python is case-sensitive. 'Score', 'score', and 'SCORE' are three completely different identifiers. This catches a lot of beginners who accidentally mix cases when referencing a variable they defined earlier.
Beyond the hard rules, the Python community follows PEP 8 — the official Python style guide. PEP 8 says: use lowercase_with_underscores for variables and functions ('player_score', not 'playerScore'), use CapitalisedWords for class names ('GamePlayer', not 'game_player'), and use ALL_CAPS_WITH_UNDERSCORES for constants ('MAX_SPEED = 300'). These aren't enforced by the interpreter, but every professional Python codebase follows them, and code reviewers will notice immediately if you don't.
Underscores carry special meaning too. A single leading underscore like '_internal_counter' signals to other developers that this is intended for internal use only. A double leading underscore like '__player_id' triggers Python's name mangling inside classes. And '__dunder__' names (double underscore on both sides) are Python's special method names like '__init__' and '__str__'.
# ── LEGAL IDENTIFIERS ───────────────────────────────────────────────────────── player_name = "Alice" # lowercase_with_underscores — PEP 8 for variables player_score = 0 # digits are fine anywhere except the first position MAX_LEVEL = 100 # ALL_CAPS signals a constant — never meant to change _checkpoint_data = [1, 5, 9] # single leading underscore = internal/private use print(f"Player: {player_name}") print(f"Score: {player_score}") print(f"Max level: {MAX_LEVEL}") print(f"Checkpoints: {_checkpoint_data}") # ── CASE SENSITIVITY IN ACTION ──────────────────────────────────────────────── total_coins = 50 # variable 'total_coins' — lowercase Total_Coins = 200 # COMPLETELY different variable — Python sees a new name entirely print(f"\ntotal_coins = {total_coins}") # prints 50 print(f"Total_Coins = {Total_Coins}") # prints 200 — different variable! # ── PEP 8 CLASS NAMING ──────────────────────────────────────────────────────── class GamePlayer: # CapitalisedWords (PascalCase) for class names def __init__(self, name): # __init__ is a dunder — Python's constructor method self.name = name # 'self.name' stores the player's name on the object new_player = GamePlayer("Bob") # create an instance of GamePlayer print(f"\nNew player name: {new_player.name}") # ── WHAT HAPPENS WITH ILLEGAL NAMES — commented out to allow file to run ────── # 1player = "invalid" # SyntaxError: starts with a digit # player-name = "invalid" # SyntaxError: hyphens are not allowed # for = 10 # SyntaxError: 'for' is a keyword
Score: 0
Max level: 100
Checkpoints: [1, 5, 9]
total_coins = 50
Total_Coins = 200
New player name: Bob
Keywords by Category — Understanding What Each Group Actually Does
Staring at 35 keywords in alphabetical order is overwhelming. Group them by what they do and the list becomes far more manageable — and far more meaningful.
The value keywords are the simplest: 'True', 'False', and 'None'. These are Python's only built-in literal constants. You'll use all three constantly.
The control-flow keywords — 'if', 'elif', 'else', 'for', 'while', 'break', 'continue', 'pass' — control the direction your code takes. Think of these as the signposts and junctions on a road.
The function and class keywords — 'def', 'return', 'lambda', 'class', 'yield' — are how you define reusable code blocks. 'lambda' creates a tiny one-liner function. 'yield' turns a function into a generator.
The error-handling keywords — 'try', 'except', 'finally', 'raise', 'assert' — are how Python deals with things going wrong. You'll reach for these the moment your programs start handling user input or file operations.
The import keywords — 'import', 'from', 'as' — bring external code into your file. 'as' lets you rename something on import, like 'import numpy as np'.
The scope keywords — 'global', 'nonlocal' — tell Python where a variable lives. The logical operators — 'and', 'or', 'not', 'in', 'is' — build conditions. And 'with', 'del', 'async', 'await' handle context management, deletion, and asynchronous programming respectively.
# This single program intentionally demonstrates keywords from every category. # Read each section's comment to see which keyword group is in play. # ── VALUE KEYWORDS: True, False, None ──────────────────────────────────────── game_active = True # True — one of only two boolean values high_score_set = False # False — the other boolean value last_winner = None # None — represents 'no value yet' print("=== Game State ===") print(f"Game active: {game_active}") print(f"High score set: {high_score_set}") print(f"Last winner: {last_winner}") # ── CONTROL FLOW KEYWORDS: if, elif, else, for, while, break, continue, pass ── player_lives = 3 current_level = 7 print("\n=== Difficulty Check ===") if current_level >= 10: # 'if' starts a condition block print("Expert territory!") elif current_level >= 5: # 'elif' = else-if — checked only if 'if' was False print("Mid-game — stay sharp.") # this branch runs: level is 7 else: # 'else' catches everything else print("Just getting started.") print("\n=== Inventory Scan ===") inventory = ["sword", "shield", "potion", "torch", "map"] for item in inventory: # 'for' loops over each item in the list if item == "potion": # skip the potion — keep it for emergencies continue # 'continue' jumps straight to the next iteration if item == "torch": break # 'break' exits the loop entirely when torch found print(f" Equipped: {item}") print("\n=== Lives Countdown ===") while player_lives > 0: # 'while' keeps looping as long as condition is True print(f" Lives remaining: {player_lives}") player_lives -= 1 # subtract 1 each iteration to avoid infinite loop # ── FUNCTION KEYWORDS: def, return, lambda ──────────────────────────────────── print("\n=== Scoring Functions ===") def calculate_bonus(base_score, multiplier): # 'def' defines a reusable function """Returns the final score after applying the bonus multiplier.""" bonus_score = base_score * multiplier return bonus_score # 'return' sends the result back to caller double_points = lambda score: score * 2 # 'lambda' — a one-liner function final_score = calculate_bonus(150, 3) print(f"Bonus score: {final_score}") print(f"Doubled score: {double_points(final_score)}") # ── ERROR-HANDLING KEYWORDS: try, except, finally, raise ────────────────────── print("\n=== Safe Division ===") def safe_divide(total_points, number_of_players): try: # 'try' — attempt this risky operation result = total_points / number_of_players except ZeroDivisionError: # 'except' — caught! handle the error print(" Can't divide by zero players — game not started yet.") return None finally: # 'finally' — runs whether error or not print(" Division attempt complete.") return result print(safe_divide(900, 3)) # normal case print(safe_divide(900, 0)) # triggers ZeroDivisionError # ── LOGICAL / MEMBERSHIP KEYWORDS: and, or, not, in, is ────────────────────── print("\n=== Win Condition ===") has_key = True boss_defeated = True if has_key and boss_defeated: # 'and' — both must be True print("You win! Both conditions met.") print(f"'map' in inventory: {'map' in inventory}") # 'in' checks membership print(f"last_winner is None: {last_winner is None}") # 'is' checks identity
Game active: True
High score set: False
Last winner: None
=== Difficulty Check ===
Mid-game — stay sharp.
=== Inventory Scan ===
Equipped: sword
Equipped: shield
=== Lives Countdown ===
Lives remaining: 3
Lives remaining: 2
Lives remaining: 1
=== Scoring Functions ===
Bonus score: 450
Doubled score: 900
=== Safe Division ===
Division attempt complete.
300.0
Can't divide by zero players — game not started yet.
Division attempt complete.
None
=== Win Condition ===
You win! Both conditions met.
'map' in inventory: True
last_winner is None: True
| Aspect | Keywords | Identifiers |
|---|---|---|
| Who defines them? | Python itself — built into the language | You — the programmer decides the name |
| Can you change their meaning? | No — fixed forever, SyntaxError if misused | Yes — you define what they hold or do |
| Total count | Exactly 35 in Python 3.12 | Unlimited — as many as your program needs |
| Case sensitivity | Case matters: True ≠ true (true is NOT a keyword) | Case matters: score ≠ Score ≠ SCORE |
| Can start with a digit? | N/A — fixed names set by Python | No — '1score' is a SyntaxError |
| Can contain hyphens? | N/A | No — 'player-score' is a SyntaxError; use 'player_score' |
| PEP 8 convention | Already follow the spec — no choice | snake_case for vars/functions, PascalCase for classes, ALL_CAPS for constants |
| Checked at runtime? | No — checked at parse time (before code runs) | Partially — undefined identifiers raise NameError at runtime |
| Tool to inspect them | keyword.kwlist / keyword.iskeyword() | dir() shows all names in current scope |
🎯 Key Takeaways
- Python has exactly 35 keywords — they are owned by the language, never by you. Use 'keyword.iskeyword()' to check any word you're unsure about before using it as a name.
- Identifiers follow four hard rules: letters/digits/underscores only, can't start with a digit, can't be a keyword, no spaces or special characters. Break any one rule and Python won't even start running your code.
- Python is strictly case-sensitive in both keywords and identifiers — 'while' is a keyword, 'While' is a valid (but terrible) variable name; 'player_score' and 'Player_Score' are two completely separate variables.
- Built-ins like 'list', 'print', 'str', and 'input' are NOT keywords but shadowing them by using them as variable names causes silent, hard-to-debug runtime failures — treat them as if they were reserved.
⚠ Common Mistakes to Avoid
- ✕Mistake 1: Using a built-in name like 'list', 'input', 'print', or 'str' as a variable name — Symptom: your code silently stops working or throws 'TypeError: 'list' object is not callable' — Fix: rename your variable to something descriptive like 'player_list' or 'score_list'. Note that 'list', 'print', 'str', 'int', and 'input' are NOT keywords (keyword.iskeyword() returns False for them) but they ARE built-in names. Overwriting them doesn't cause a SyntaxError — it causes confusing runtime bugs that are hard to trace. Run 'dir(__builtins__)' to see every name you should avoid.
- ✕Mistake 2: Using hyphens in variable names instead of underscores — Symptom: SyntaxError on a line like 'player-score = 100' — Fix: Python interprets the hyphen as a minus operator, so it tries to evaluate 'player minus score = 100', which makes no sense. Always use underscores: 'player_score = 100'. This is the single most common identifier mistake from developers coming from CSS or HTML backgrounds.
- ✕Mistake 3: Assuming Python keywords are case-insensitive — Symptom: Using 'While', 'IF', or 'TRUE' expecting them to work like keywords — 'While True:' raises a SyntaxError because 'While' with a capital W is not a keyword; only 'while' (lowercase) is. The three exceptions are 'True', 'False', and 'None' which must be capitalised exactly as written. Fix: always type keywords in lowercase except for those three — your code editor's syntax highlighting will confirm whether you've got it right.
Interview Questions on This Topic
- QCan you name five Python keywords and explain what each one does? (Interviewers ask this to check whether you actually write Python or just read about it — they expect you to reach for 'if', 'for', 'def', 'return', and 'None' or 'True'/'False' and explain them naturally, not recite a memorised list.)
- QWhat is the difference between a keyword and a built-in in Python? (Most beginners don't know this distinction. Keywords like 'for' and 'if' are reserved at the parser level — you can't use them as names at all. Built-ins like 'list', 'print', and 'len' are just names defined in Python's built-in namespace — you CAN overwrite them, which is exactly why you shouldn't. A SyntaxError means you've hit a keyword; a broken built-in is silent and dangerous.)
- QWhy does Python use 'is None' rather than '== None' when checking for None values? (This trips up a lot of people. '==' calls the '__eq__' method, which can be overridden by any custom class to return whatever it wants — so '== None' could theoretically return True for something that isn't None. 'is' checks object identity directly in memory, and since None is a singleton — there is exactly one None object in any Python program — 'is None' is guaranteed to be correct. PEP 8 mandates 'is None' for this reason.)
Frequently Asked Questions
How many keywords does Python have?
Python 3.12 has exactly 35 keywords. This number has changed across Python versions — Python 3.5 added 'async' and 'await', for example. You can always get the exact count for your version by running 'import keyword; print(len(keyword.kwlist))' in your Python environment.
Is 'None' a keyword in Python?
Yes, 'None' is one of Python's 35 keywords — and it must be written with a capital N. It represents the complete absence of a value, similar to 'null' in other languages. 'none' (all lowercase) is not a keyword and could technically be used as a variable name, though doing so is a recipe for confusion.
What is the difference between a Python keyword and an identifier?
A keyword is a word with a fixed, built-in meaning that Python's interpreter recognises before your code even runs — you cannot use keywords as variable names. An identifier is a name you choose for your own variables, functions, and classes — it follows Python's naming rules but its meaning is entirely up to you. Keywords are the language's vocabulary; identifiers are your vocabulary inside that language.
Written and reviewed by senior developers with real-world experience across enterprise, startup and open-source projects. Every article on TheCodeForge is written to be clear, accurate and genuinely useful — not just SEO filler.