Variables in Python

Suppose we're writing a greeting program. We don't know the user's name in advance: it will only appear when the program runs. So in our code we need a way to refer to that future name without knowing it yet. That's exactly what variables are for.

Python 3.13
name = "John"
print("Hello, " + name + "!")

In this code name is a label that tells Python where the string "John" lives in memory. Whenever name appears later, Python looks at what the label points to and substitutes the value.

A variable as a label pointing to an object in memory

What is a variable?

A variable in Python is a name bound to an object in memory. Python infers the object's type automatically, and that binding can be changed at any time.

Three conveniences follow from this:

  • you don't have to declare a variable beforehand: it appears on the first assignment
  • you don't have to specify the type: Python sees what's on the right and remembers
  • you can rebind a name to another value at any moment

Creating and using variables

A variable is created with the = operator. The name goes on the left, the value the name will point to goes on the right:

Python 3.13
# Creating variables of different types
name = "John"          # String variable
age = 25               # Integer variable
height = 1.85          # Float variable
is_student = True      # Boolean variable
courses = ["Python", "SQL", "JavaScript"]  # List variable

Once created, you can use the name anywhere its value is needed:

Python 3.13
name = "John"
print("Hello, " + name + "!")
Hello, John!
age = 25
next_year_age = age + 1
print(f"Next year you'll be {next_year_age} years old")
Next year you'll be 26 years old

Multiple assignment

The most common use is unpacking: a collection on the right, several names on the left. They receive the values in order:

Python 3.13
coordinates = (10, 20, 30)
x, y, z = coordinates
print(f"x={x}, y={y}, z={z}")
x=10, y=20, z=30

The same logic gives an elegant way to swap two variables without a temporary one:

Python 3.13
a = 5
b = 10
a, b = b, a
print(f"a = {a}, b = {b}")
a = 10, b = 5

The right side first builds a tuple (10, 5), then it's unpacked into the left side. No third variable needed.

You can also assign a single value to several names via a chain of =:

Python 3.13
x = y = z = 0

This rarely shows up in real code; three separate lines are usually clearer. And with mutable objects the chain creates a single shared reference: a = b = [] makes a and b the same list, which is almost never what you wanted.

Dynamic typing

Python is a dynamically typed language. The type of a variable is determined at runtime and can change when a new value is assigned:

Python 3.13
x = 10 # x has type int (integer)
print(f"x = {x}, type: {type(x)}")
x = 10, type: <class 'int'>
x = "ten" # now x has type str (string)
print(f"x = {x}, type: {type(x)}")
x = ten, type: <class 'str'>
x = [1, 2, 3] # now x has type list (list)
print(f"x = {x}, type: {type(x)}")
x = [1, 2, 3], type: <class 'list'>

To check the current type of a variable, use the built-in type() function:

Python 3.13
name = "John"
age = 25
height = 1.85
is_student = True

print(f"{name}: {type(name)}")
John: <class 'str'>
print(f"{age}: {type(age)}")
25: <class 'int'>
print(f"{height}: {type(height)}")
1.85: <class 'float'>
print(f"{is_student}: {type(is_student)}")
True: <class 'bool'>

Naming variables in Python

Good variable names make code understandable and maintainable.

Naming rules

  1. Names can contain letters, digits and the underscore (a-z, A-Z, 0-9, _).
  2. A name must start with a letter or underscore.
  3. You can't use Python's reserved words (e.g., if, for, class).
Python 3.13
# Valid names
name = "John"
age_in_years = 25
_private_variable = "Non-public information"

# Invalid names
# 2name = "Cannot start with a digit"
# my-name = "Cannot use hyphens"
# class = "Reserved word"

Best practices for naming variables

The Python community has an official style guide, PEP 8. It's not law, but almost all Python code you'll encounter follows it. Your own code will be easier to read if it looks the same.

  1. Use descriptive names: let the name say what it's for
Python 3.13
# Better ✅
user_age = 25

# Than this ❌
a = 25

A month later you'll come back to your own code, and a will tell you nothing. user_age is a free hint to the reader.

  1. Use snake_case (lowercase words joined by underscores)
Python 3.13
# Python style ✅
first_name = "John"

# Not Python style ❌
firstName = "John"

Technically both work. But all the Python code around you is in snake_case, and switching between styles within a project tires the eye.

  1. Prefix is_ or has_ for boolean variables
Python 3.13
is_adult = True
has_permission = False

When you see if is_adult:, it's immediately clear that the right side is a boolean, not, say, a number of years or a user object. Without the prefix, adult doesn't give you that hint.

  1. UPPER_CASE for constants
Python 3.13
MAX_ATTEMPTS = 3
PI = 3.14159

Python has no true constants: you can rebind MAX_ATTEMPTS and the language won't complain. But the convention "anything in uppercase is off-limits" is universal, and everyone respects it.

  1. Avoid overly short names
Python 3.13
# Bad ❌
n = "John"
flag = True
str1 = "String"

# Good ✅
user_name = "John"
is_verified = True
welcome_message = "Welcome!"

A few extra characters at writing time save minutes at reading time. And code gets read far more often than it's written.

Case sensitivity

Python is case-sensitive, which means uppercase and lowercase letters are different in variable names. The variables name, Name, and NAME are interpreted as three different variables:

Python 3.13
name = "John"
Name = "Peter"
NAME = "Alex"

print(name)
John
print(Name)
Peter
print(NAME)
Alex

Three different variables: changing the case in a variable name creates a completely new one.

Practice tasks

Right below this article there's a block called Practice tasks. It's where you can immediately try out what you've just read.

What's already in the editor

Most tasks come with code that's partially filled in. This is intentional: you only need to add the part the lesson actually covered. Everything else is scaffolding the system needs to verify your answer. Here's what it looks like:

Task structure: where to fill in values, what not to touch, what the "Check" button does

The left side is the task description: what to name and with which values. The colored badges in the description (for example, John, 25, True) are the exact values the code expects.

In the editor on the right, lines 1–3 (the ones with = but no value) are where the values from the task go. Lines 5–7 (with print(...)) shouldn't be touched: they're how the system sees your result and compares it against the expected one.

The "Check" button runs your code and compares its output to the expected one. You can press it as many times as you like: errors don't affect anything, and the variables inside the task live their own life.

Reading the result

If the code is correct, you'll see a green "Solution correct" plus two matching boxes: "Your result" and "Expected result".

How to read the result: the checkmark means it's correct, the two boxes should match line by line, there may be multiple tests

If something differs, the system shows exactly which line. A task can have more than one test (Test 1, Test 2, and so on), for example to check your code against different inputs. All of them must pass for the task to count.


In the next lesson we'll look at where a variable lives: why a name declared inside a function isn't visible outside, and vice versa.