Variable Assignment
Variable Assignment
In every programming language, a variable is simply a label, a name you choose, that lets you refer to a piece of information stored in your computer's memory. Think of it a bit like a labelled box: you don't need to know exactly where in memory a value physically lives, you just need to remember the name you gave it. In this activity, you'll get hands-on practice with variables in Python, and see how assignment statements are used to store a value, update it later, and retrieve it whenever you need it.
For example:
# Assigning a value to a variable
age = 25
# Retrieving the value by using its name
print(age) # Output: 25
# Updating the variable to a new value
age = 26
print(age) # Output: 26
Here, age is the variable name, and the = sign is the assignment operator, it takes the value on the right and stores it under the name on the left. Once a variable has been assigned, you can use it anywhere in your code simply by referring to its name.
Choosing meaningful, descriptive variable names is one of the most valuable habits you can build as a new programmer. Consider the difference between these two examples, which do exactly the same thing:
# Hard to understand at a glance
x = 9.99
y = 3
z = x * y
print(z)
# Much clearer, and easier to check for mistakes
price_per_item = 9.99
quantity = 3
total_cost = price_per_item * quantity
print(total_cost)
Both versions work, but the second is far easier to read, debug, and hand over to someone else, including your future self, returning to the code weeks later. Good variable names act almost like built-in comments, making your intentions clear without needing extra explanation.
One thing to be aware of: Python reserves a small set of special keywords for its own language syntax, words like if, for, class, and True, and these cannot be used as variable names, since Python needs them to mean something very specific. Trying to use one will raise an error:
# This will cause a SyntaxError, because 'True' is a reserved keyword
True = 5
Don't worry about memorising every reserved keyword right away, you'll get used to spotting them naturally as you write more Python, and most code editors will highlight them in a different colour to warn you.
Reserved Keywords in Python
Python sets aside a small collection of special words, called reserved keywords, that already have a fixed, built-in meaning within the language itself. Because Python relies on these words to understand the structure of your code, for example, to recognise a loop, define a function, or check a condition, none of them can be used as variable names. Trying to do so will cause Python to raise a SyntaxError, since it will attempt to interpret the word as an instruction rather than as a label you're trying to create.
# Trying to use a keyword as a variable name fails immediately
for = 5
# SyntaxError: invalid syntax
The Full List of Keywords
As of recent versions of Python, there are 35 reserved keywords in total. It can help to think of them not as one big list to memorise, but as a handful of small, logical groups, each serving a different purpose in the language.
Boolean and special values
| Keyword | Meaning |
|---|---|
True |
Represents the boolean value true |
False |
Represents the boolean value false |
None |
Represents the absence of a value |
is_active = True
has_error = False
result = None
print(is_active, has_error, result) # Output: True False None
Logical and comparison operators
| Keyword | Meaning |
|---|---|
and |
Logical AND |
or |
Logical OR |
not |
Logical negation |
in |
Membership test (e.g. x in my_list) |
is |
Identity comparison (e.g. x is None) |
age = 25
has_id = True
# 'and' / 'or' / 'not' combine conditions
if age >= 18 and has_id:
print("Entry allowed")
if age < 18 or not has_id:
print("Entry denied")
# 'in' checks membership
fruits = ["apple", "banana", "cherry"]
print("banana" in fruits) # True
# 'is' checks identity, not just equality
x = None
print(x is None) # True, this is the preferred way to check for None
Control flow
| Keyword | Meaning |
|---|---|
if, elif, else |
Conditional branching |
for, while |
Loops |
break, continue |
Alter loop behaviour |
pass |
A placeholder that does nothing |
score = 72
# if / elif / else
if score >= 90:
grade = "A"
elif score >= 70:
grade = "B"
else:
grade = "C"
print(grade) # Output: B
# for loop with break and continue
for number in range(10):
if number == 3:
continue # skip printing 3
if number == 6:
break # stop the loop entirely once we reach 6
print(number)
# pass as a placeholder, useful when writing a function or class before filling it in
def not_yet_implemented():
pass
Functions and structure
| Keyword | Meaning |
|---|---|
def |
Defines a function |
return |
Returns a value from a function |
lambda |
Creates a small, unnamed function |
class |
Defines a class |
yield |
Returns a value from a generator function |
global |
Refers to a variable at the module level |
nonlocal |
Refers to a variable in an enclosing (but non-global) scope |
# def and return
def square(x):
return x * x
print(square(4)) # Output: 16
# lambda: a quick, unnamed function
double = lambda x: x * 2
print(double(5)) # Output: 10
# class: defines a new object type
class Dog:
def __init__(self, name):
self.name = name
my_dog = Dog("Rex")
print(my_dog.name) # Output: Rex
# yield: used in generator functions, producing values one at a time
def count_up_to(n):
i = 1
while i <= n:
yield i
i += 1
for number in count_up_to(3):
print(number) # Output: 1 2 3
# global vs nonlocal
counter = 0
def increment():
global counter
counter += 1
increment()
print(counter) # Output: 1
Importing code
| Keyword | Meaning |
|---|---|
import |
Loads a module |
from |
Imports specific parts of a module |
as |
Creates an alias, e.g. import numpy as np |
import math
print(math.sqrt(16)) # Output: 4.0
from math import pi
print(pi) # Output: 3.141592653589793
import pandas as pd # 'as' creates a shorter alias
Exception handling
| Keyword | Meaning |
|---|---|
try, except, finally |
Handle errors gracefully |
raise |
Manually triggers an error |
assert |
Checks that a condition holds, raising an error if not |
try:
result = 10 / 0
except ZeroDivisionError:
print("You can't divide by zero!")
finally:
print("This runs whether or not an error occurred.")
# raise: manually trigger an error
age = -1
if age < 0:
raise ValueError("Age cannot be negative")
# assert: a quick sanity check, useful when testing code
assert age >= 0, "Age should never be negative"
Context management and deletion
| Keyword | Meaning |
|---|---|
with |
Manages resources such as open files |
del |
Deletes a variable or item |
# with: automatically closes the file afterwards, even if an error occurs
with open("example.txt", "w") as f:
f.write("Hello, world!")
# del: removes a variable or list item entirely
scores = [10, 20, 30]
del scores[1]
print(scores) # Output: [10, 30]
Asynchronous programming (introduced in Python 3.5+, made full reserved keywords in Python 3.7)
| Keyword | Meaning |
|---|---|
async |
Declares an asynchronous function |
await |
Waits for an asynchronous operation to complete |
import asyncio
async def fetch_data():
print("Fetching...")
await asyncio.sleep(1) # pauses here without blocking the whole program
print("Done!")
asyncio.run(fetch_data())
Checking the List Yourself
Rather than relying on memory, Python lets you check the current, authoritative list of keywords directly, which is useful since the exact list can change slightly between versions:
import keyword
print(keyword.kwlist)
print(len(keyword.kwlist)) # Confirms how many keywords exist in your version
A Special Case: "Soft Keywords"
Since Python 3.10, a small number of words behave as soft keywords. These words have special meaning only in specific contexts, but remain perfectly valid as variable names everywhere else. This is a deliberate design choice, allowing Python to add new syntax (such as the match statement) without breaking existing code that may already be using these words as variable names.
The current soft keywords are: match, case, type, and _.
# 'match' is used here as a soft keyword, introducing a match statement
command = "start"
match command:
case "start":
print("Starting...")
case "stop":
print("Stopping...")
case _:
print("Unknown command") # '_' acts as a wildcard/default case here
# But 'match' is also perfectly valid as an ordinary variable name elsewhere
match = 5
print(match) # Output: 5
# Likewise, 'type' is a soft keyword/built-in name, but can be reassigned (see pitfall below)
type = "reassigned"
print(type) # Output: reassigned
You can check the current soft keywords the same way:
print(keyword.softkwlist)
A Common Pitfall: Built-in Names That Aren't Keywords
A frequent source of confusion for learners is the difference between reserved keywords and built-in function or type names, such as print, list, str, int, len, or type. These are not reserved keywords at all, they're simply predefined names that Python provides in its standard library. This means Python will not stop you from reassigning them:
# This is technically allowed, but strongly discouraged
list = [1, 2, 3]
# Now 'list' no longer refers to Python's built-in list type,
# so this will raise a TypeError instead of creating a new list
new_list = list("hello")
# TypeError: 'list' object is not callable
Another common example of this pitfall:
# Overwriting the built-in 'str' function
str = "some text"
# Now trying to convert a number to text will fail
value = str(42)
# TypeError: 'str' object is not callable
Because no error is raised at the moment of reassignment, this kind of mistake can be especially confusing to debug, since the problem often only becomes apparent several lines later, when the built-in function is needed again but no longer behaves as expected. As a good habit, avoid using built-in names as variable names, even though Python permits it. If you accidentally do this in a Jupyter Notebook, restarting the kernel will restore the original built-in.
Case Sensitivity
Python keywords are case-sensitive, so only the exact casing shown in the list above is reserved. This means, somewhat surprisingly to new learners, that a word like true or NONE is perfectly valid as a variable name, even though True and None are not:
true = "yes" # Valid, since Python's keyword is 'True', not 'true'
NONE = "empty" # Valid, since Python's keyword is 'None', not 'NONE'
Class = "MyClass" # Valid, since Python's keyword is 'class', not 'Class'
print(true, NONE, Class) # Output: yes empty MyClass
That said, using near-identical variations of keywords like this is generally poor practice, since it can easily confuse readers of your code, or even yourself when returning to it later.
Quick Self-Check
If you're ever unsure whether a particular word is reserved, there are two quick ways to check without needing to look anything up:
import keyword
# Method 1: check directly
print(keyword.iskeyword("class")) # True
print(keyword.iskeyword("dataframe")) # False
print(keyword.iskeyword("match")) # False, since it's a soft keyword, not a full keyword
print(keyword.issoftkeyword("match")) # True
# Method 2: just try assigning it in a notebook cell
# If Python raises a SyntaxError, the word is reserved
Getting comfortable with this small set of reserved words early on will save you time later, since encountering a SyntaxError caused by an accidental keyword clash is a common early stumbling block, but a very quick one to resolve once you know what to look for.