Python Variables & Data Types
This lesson assumes you have completed Lesson 1: Welcome & Hello World. You should know how to write a print() statement and run code in our online compiler. No prior programming experience required beyond that.
- How Python variables work and how to create them
- The four core data types: int, float, str, and bool
- How to check a variable's type with
type() - Variable naming rules and Python naming conventions
- How to convert between types (type casting)
- The difference between mutable and immutable types
- How to define constants using UPPER_CASE convention
- Common beginner mistakes and how to avoid them
In Python, a variable is simply a name that points to a value stored in your computer's memory. Unlike languages such as C or Java, Python never requires you to declare a variable's type before using it — you just write name = value, and Python figures out the type automatically.
This makes Python extremely beginner-friendly, but it also means you need to understand how Python thinks about types internally. This lesson walks you through every detail, with real annotated examples you can run instantly in our online compiler.
Creating a variable in Python takes exactly one step: assign a value to a name using the = operator. There is no "declare" step, no type keyword, and no semicolon needed.
name = "Alice" # str — text inside quotes
age = 28 # int — whole number
height = 1.68 # float — decimal number
is_student = True # bool — True or False
print(name)
print(age)
print(height)
print(is_student)
Python reads the right side of =, determines the type from the value, and stores both the value and its type in memory under the name you chose. The equals sign here is the assignment operator, not a mathematical equality check.
You can also assign multiple variables on one line using Python's tuple unpacking shorthand:
# Assign multiple variables at once
x, y, z = 10, 20, 30
print(x, y, z) # 10 20 30
# Assign the same value to multiple names
a = b = c = 0
print(a, b, c) # 0 0 0
Python has four built-in primitive data types that you'll use in virtually every program you write. Understanding them deeply is essential before moving to lists, dictionaries, and objects.
2.1 int — Whole Numbers
int stores whole numbers of any size — positive, negative, or zero. Python integers are not limited to 32 or 64 bits like in C or Java; they can grow to any size your RAM allows.
population = 8_000_000_000 # underscores improve readability
negative = -42
big_num = 999999999999999999999 # Python handles any size!
print(population)
print(type(population)) # <class 'int'>
2.2 float — Decimal Numbers
float stores numbers with a fractional part. Internally, Python uses 64-bit double-precision floating-point (IEEE 754), which gives you about 15–17 significant decimal digits of accuracy.
pi = 3.14159265358979
temperature = -7.5
small = 0.000_001 # scientific-style
print(pi)
print(type(pi)) # <class 'float'>
# Beware of floating-point precision:
print(0.1 + 0.2) # 0.30000000000000004 ← expected in IEEE 754
2.3 str — Text Strings
str stores any sequence of characters — letters, digits, spaces, emoji, or symbols. Strings can be wrapped in single quotes, double quotes, or triple quotes for multiline text.
greeting = "Hello, World!"
city = 'Hyderabad'
multiline = """Line one
Line two
Line three"""
# f-strings let you embed variables directly
name = "Balaji"
message = f"Welcome, {name}! You are learning Python."
print(message)
2.4 bool — True or False
bool has exactly two possible values: True and False (capital T and F — Python is case-sensitive). Booleans are the foundation of all conditional logic and are technically a subtype of int in Python (True == 1 and False == 0).
is_logged_in = True
has_premium = False
print(is_logged_in) # True
print(type(has_premium)) # <class 'bool'>
# Booleans are ints under the hood:
print(True + True) # 2
print(True * 10) # 10
print(int(False)) # 0
type()The built-in type() function tells you the exact data type of any variable or value. This is invaluable for debugging, especially because Python can silently change what type a variable holds.
print(type(42)) # <class 'int'>
print(type(3.14)) # <class 'float'>
print(type("hello")) # <class 'str'>
print(type(True)) # <class 'bool'>
print(type(None)) # <class 'NoneType'>
# isinstance() — better for conditional checks:
x = 100
if isinstance(x, int):
print("x is an integer!")
None — it represents the absence of a value, similar to null in other languages. Its type is NoneType. You'll encounter it often in functions that don't explicitly return a value.
Use this table as a quick cheat sheet whenever you need to compare the core Python types:
| Type | Example | Description | Mutable? | Typical Use |
|---|---|---|---|---|
int |
42, -7, 0 |
Whole numbers, unlimited size | No | Counting, indexing, loops |
float |
3.14, -0.5 |
Decimal numbers (64-bit IEEE 754) | No | Math, measurements, percentages |
str |
"hello", 'abc' |
Sequence of Unicode characters | No | Names, messages, text processing |
bool |
True, False |
Logic values, subtype of int | No | Conditions, flags, toggles |
NoneType |
None |
Represents "no value" | No | Default function returns, optional values |
Python enforces some rules for variable names (your code will crash if you break them) and has conventions that are best practices (your code still runs, but it looks unprofessional).
| Category | Rule / Convention | Example |
|---|---|---|
| ✅ Valid characters | Letters, digits, underscore _ only |
score_1, _count |
| ❌ Can't start with digit | First character must be a letter or _ |
1name → SyntaxError |
| ❌ Reserved words | Can't use Python keywords | class, for, if → error |
| ⚠️ Case-sensitive | Name and name are different variables |
Age = 30 vs age = 30 |
| ✅ Style: snake_case | Use underscores for multi-word names (PEP 8) | user_name, total_score |
| ✅ Style: UPPER_CASE | Constants use all-caps (convention, not enforced) | MAX_RETRIES = 3 |
x = 42 # meaningless
a1 = "Alice" # cryptic
MyVar = True # camelCase (not Pythonic)
class = "math" # reserved word → crashes!
student_age = 42
student_name = "Alice"
is_enrolled = True
MAX_STUDENTS = 30 # constant
Python does not automatically convert between types the way JavaScript does. If you want to combine an integer with a string, you must explicitly convert first. This explicit approach prevents many hidden bugs.
age = 25
score = 97.8
user_input = "42" # comes in as string from input()
# str() — convert to string for concatenation
print("Age: " + str(age)) # "Age: 25"
# int() — convert string or float to integer
print(int(user_input) + 8) # 50
print(int(score)) # 97 (truncates, no rounding!)
# float() — convert int or string to float
print(float("3.14")) # 3.14
print(float(10)) # 10.0
# bool() — falsy vs truthy
print(bool(0)) # False ← zero is falsy
print(bool("")) # False ← empty string is falsy
print(bool("hello")) # True ← any non-empty string is truthy
print(bool(42)) # True ← any non-zero number is truthy
The input() function always returns a string — even if the user types a number. So age = input("Enter age: ") gives you "25" as a string, not the integer 25. Always wrap with int() or float() when you need to do math:
# WRONG — this crashes with TypeError
age = input("Enter your age: ")
print(age + 5) # TypeError: can only concatenate str (not "int") to str
# CORRECT — convert first
age = int(input("Enter your age: "))
print(age + 5) # works perfectly!
Python has no built-in const keyword. Instead, the community convention (PEP 8) is to write constants in UPPER_CASE_WITH_UNDERSCORES at the top of your file. This signals to other developers: "don't change this value."
# Constants — by convention, UPPER_CASE
MAX_LOGIN_ATTEMPTS = 5
PI = 3.14159265358979
APP_VERSION = "2.1.0"
DATABASE_URL = "postgresql://localhost/mydb"
# Usage in code
attempts = 0
while attempts < MAX_LOGIN_ATTEMPTS:
print(f"Attempt {attempts + 1} of {MAX_LOGIN_ATTEMPTS}")
attempts += 1
If you need truly immutable constants in a serious project, Python developers typically use the Final type hint from Python 3.8+: from typing import Final; MAX: Final = 100. This doesn't prevent reassignment at runtime but causes static type checkers like mypy to flag it as an error.
Python variables are not "typed containers" — they are references (pointers) to objects. When you write x = 10, Python creates an int object with value 10 in memory, and x becomes a reference pointing to it. When you later write x = "hello", x now points to a new str object — the old int object is garbage-collected if nothing else references it.
This is why Python is called dynamically typed: the type travels with the object, not the variable name. You can verify this with id(), which returns the memory address of an object:
x = 10
print(id(x)) # e.g. 140723456788080
x = 10 # CPython caches small ints (-5 to 256)
print(id(x)) # same address — Python reuses the cached object!
x = 99999999 # large int — new object
print(id(x)) # different address each run
This object-reference model is the reason Python handles reassignment, multiple assignment, and function arguments the way it does — understanding it will save you hours of debugging later.
Python will raise a NameError if you try to use a variable that hasn't been assigned yet. Unlike some languages, there is no "default" value for an uninitialized variable.
print(total) # NameError: name 'total' is not defined
total = 0
print(total) # 0 — works now
A single = assigns a value to a variable. Two equals == checks whether two values are equal and returns True or False. Mixing these up is one of the most common bugs in all of programming.
score = 95 # assignment — score is now 95
score == 100 # comparison — returns False (no output unless printed!)
print(score == 100) # False
print(score == 95) # True
Python does not auto-convert types the way JavaScript does. Adding a string to a number crashes immediately.
price = 49.99
message = "Total: " + price # TypeError! Can't add str + float
# Fix: convert explicitly
message = "Total: " + str(price) # "Total: 49.99"
# Or better, use an f-string:
message = f"Total: {price}" # "Total: 49.99"
print(message)
student_name (str), student_age (int), gpa (float), and is_enrolled (bool). Print each one with type() to verify, then print a formatted summary sentence using an f-string.
student_name = "Riya Sharma"
student_age = 20
gpa = 3.85
is_enrolled = True
# Print each variable and its type
print(student_name, type(student_name))
print(student_age, type(student_age))
print(gpa, type(gpa))
print(is_enrolled, type(is_enrolled))
# Print a formatted summary
print(f"\n{student_name} | Age: {student_age} | GPA: {gpa} | Enrolled: {is_enrolled}")
f"text {variable} more text" — expressions inside {} are evaluated and converted to strings automatically.price_str = "1499.50"
quantity_str = "3"
discount_str = "10" # percentage
# TODO: Convert to correct types and compute:
# 1. total = price * quantity
# 2. discount_amount = total * (discount / 100)
# 3. final_price = total - discount_amount
# 4. Print: "Final Price: ₹XXXX.XX" (rounded to 2 decimals)
price = float(price_str)
quantity = int(quantity_str)
discount = float(discount_str)
total = price * quantity
discount_amount = total * (discount / 100)
final_price = total - discount_amount
print(f"Total: ₹{total:.2f}")
print(f"Discount ({discount}%): -₹{discount_amount:.2f}")
print(f"Final Price: ₹{final_price:.2f}")
:.2f inside an f-string formats a float to exactly 2 decimal places — very useful for prices and percentages.- Variables are created with
=— no type declaration needed. Python determines the type from the value automatically. - Python has four primitive types:
int(whole numbers),float(decimals),str(text), andbool(True/False).Noneis also widely used to represent "no value." type()reveals the type of any variable or value at runtime. Useisinstance()for type-checking in conditions.- Type casting is explicit — use
int(),float(),str(),bool(). Python will not silently coerce types for you, unlike JavaScript. - Always wrap
input()with a conversion —input()always returns a string. Useint(input(...))orfloat(input(...))when you need numbers. - Use
snake_casefor variable names andUPPER_CASEfor constants to follow PEP 8 — Python's official style guide. - Python variables are references, not containers. They point to objects in memory, which is why two variable names can point to the same object.
A variable in Python is a named reference to an object stored in memory. When you write age = 25, Python creates an integer object 25 in memory and makes the name age point to it. Variables can be reassigned to any value at any time — you don't lock them to a particular type like in C or Java.
Yes. Python's core primitive types are int (whole numbers), float (decimals), str (text), and bool (True/False). Python automatically assigns the correct type based on the literal value you write: 5 is an int, 5.0 is a float, "5" is a str, and True/False are bool.
Use the built-in constructor functions: int(), float(), str(), and bool(). For example, int("42") converts the string "42" to the integer 42. float(10) converts the integer 10 to 10.0. Note that int(3.9) truncates to 3, not 4 — it does not round.
Yes — Python is dynamically typed, meaning type information is attached to objects (values), not to variable names. This means the same variable can hold an int at one point and a str at another: x = 5; x = "hello" is valid Python. The type is checked at runtime (when the code runs), not at compile time. This is the opposite of statically-typed languages like Java or C++, where variable types are fixed at compile time.