Variables & Data Types

Master Python's dynamic type system — integers, floats, strings, booleans, None, type conversion, and naming.

Beginner 30 min read 🐍 Python

Variables in Python

No declaration keyword needed

Unlike Java or C++, Python variables don't need a type declaration. Just assign a value and Python figures out the type.

Creating Variables

In most programming languages, you declare a variable's type before using it — like int age = 30; in Java or let age: number = 30; in TypeScript. Python takes a radically different approach: you just pick a name and assign a value. Python looks at the value and figures out the type automatically. This is called dynamic typing.

Think of a variable as a label on a box. The label (variable name) points to a box (value in memory). You can peel off the label and stick it on a different box at any time — even a box of a completely different type.

# Python infers the type automatically
name = "Alice"          # str
age = 30                # int
height = 5.7            # float
is_student = True       # bool
favorite_color = None   # NoneType

print(name, age, height, is_student)
Output
Alice 30 5.7 True

Variable Naming Rules

Choosing good variable names is one of the most important skills in programming. Your code should read almost like English. Compare x = 7_900_000_000 vs world_population = 7_900_000_000 — the second one tells you exactly what the number represents without needing a comment.

Python has a few rules for what makes a valid variable name:

RuleValidInvalid
Must start with letter or _name, _count2name
Can contain letters, digits, _my_var2my-var
Case sensitiveName ≠ name
Cannot be a keywordmy_classclass, if

Convention: use snake_case for variables and functions (like user_name), PascalCase for classes (like BankAccount), and UPPER_CASE for constants (like MAX_RETRIES). Following this convention makes your code instantly recognizable to other Python developers.

Multiple Assignment

Python has a neat trick: you can assign multiple variables in a single line. This is called tuple unpacking and it's used everywhere in Python — from swapping variables to iterating over dictionaries. It's one of those features that feels magical the first time you see it:

# Assign multiple at once
x, y, z = 1, 2, 3
print(x, y, z)

# Same value
a = b = c = 0
print(a, b, c)

# Swap variables
x, y = y, x
print(x, y)  # 2 1
Output
1 2 3
0 0 0
2 1
Key Takeaway: Python is dynamically typed — variables can hold any type and change type. The type belongs to the value, not the variable.

Numeric Types

Python has three numeric types: int for whole numbers, float for decimals, and complex for complex math (rarely used). The most important thing to know is that Python integers have unlimited precision — unlike C or Java where integers overflow at 2 billion, Python can handle numbers as large as your memory allows.

Integers

Integers in Python aren't limited to 32 or 64 bits. You can calculate a googol (10 to the 100th power) without any special libraries. Python also supports underscores in numbers for readability — 7_900_000_000 is the same as 7900000000 but much easier to read:

big = 10 ** 100  # A googol!
print(type(big))

# Underscores for readability
population = 7_900_000_000
print(f"Population: {population:,}")
Output

Population: 7,900,000,000

Arithmetic Operations

Python supports all the standard math operations plus a few extras. Pay special attention to the difference between / (true division — always returns a float) and // (floor division — rounds down to the nearest integer). The % modulo operator gives you the remainder after division, which is incredibly useful for checking if a number is even, cycling through indices, and much more:

print(10 + 3)    # 13   Addition
print(10 - 3)    # 7    Subtraction
print(10 * 3)    # 30   Multiplication
print(10 / 3)    # 3.33 True division (float)
print(10 // 3)   # 3    Floor division (int)
print(10 % 3)    # 1    Modulo
print(2 ** 10)   # 1024 Exponentiation
Output
13
7
30
3.3333333333333335
3
1
1024

Integer vs Float Division

/ always returns a float: 10 / 2 gives 5.0. Use // for integer division.

Strings

Strings are sequences of characters — text data. In Python, strings are immutable, meaning once created, they can't be changed. When you call a method like .upper(), it returns a new string rather than modifying the original. This might seem wasteful, but it makes strings safe to share between different parts of your program without worrying about unexpected changes.

Python strings support Unicode by default, meaning you can use emojis, Chinese characters, Arabic text, and more without any special configuration. This is a major improvement over Python 2, where handling non-ASCII text was painful.

Creating Strings

You can create strings with single quotes, double quotes, or triple quotes. Single and double quotes are identical — use whichever you prefer (most Python developers use double quotes by convention). Triple quotes let you write strings that span multiple lines:

s1 = 'hello'
s2 = "hello"
print(s1 == s2)  # True

# Triple quotes for multiline
poem = """Roses are red,
Violets are blue,
Python is awesome."""
print(poem)

# Raw strings
path = r"C:\Users\name\docs"
print(path)
Output
True
Roses are red,
Violets are blue,
Python is awesome.
C:\Users\name\docs

f-strings

name = "Alice"
age = 30
balance = 1234.5

print(f"{name} is {age} years old")
print(f"Next year: {age + 1}")
print(f"Balance: ${balance:,.2f}")
print(f"{name:>15}")    # right-align
print(f"{name:*^15}")   # center with *
Output
Alice is 30 years old
Next year: 31
Balance: $1,234.50
          Alice
*****Alice*****

Common String Methods

s = "  Hello, World!  "
print(s.strip())         # "Hello, World!"
print(s.lower())         # "  hello, world!  "
print(s.replace("World", "Python"))  # "  Hello, Python!  "
print(s.split(","))      # ['  Hello', ' World!  ']
print("-".join(["a","b","c"]))  # "a-b-c"
print("hello".count("l"))  # 2
Output
Hello, World!
  hello, world!  
  Hello, Python!  
['  Hello', ' World!  ']
a-b-c
2
Key Takeaway: f-strings are the most readable formatting option. Strings are immutable — methods like .upper() return NEW strings.

Booleans and None

Boolean Values

print(5 > 3)       # True
print(5 == 3)      # False
print(type(True))  # 

# Booleans are integers!
print(True + True)   # 2
print(int(False))    # 0
Output
True
False

2
0

Truthy and Falsy

# Falsy: False, 0, 0.0, "", [], {}, set(), None
print(bool(0))       # False
print(bool(""))      # False
print(bool([]))      # False
print(bool(None))    # False

# Everything else is truthy
print(bool(42))      # True
print(bool("hi"))    # True
print(bool([1,2]))   # True
Output
False
False
False
False
True
True
True

None

result = None
print(result is None)  # True — always use "is" for None

def greet(name=None):
    if name is None:
        return "Hello, stranger!"
    return f"Hello, {name}!"

print(greet())
print(greet("Alice"))
Output
True
Hello, stranger!
Hello, Alice!

Type Conversion & Checking

# String to number
age_str = "25"
print(int(age_str))      # 25
print(float(age_str))    # 25.0

# Number to string
print(str(19.99))        # "19.99"

# Type checking
x = 42
print(type(x))           # 
print(isinstance(x, int))  # True
print(isinstance(x, (int, float)))  # True
Output

True
True
🔍 Deep Dive: Everything is an Object

In Python, everything is an object — even integers, functions, and modules. Every object has an identity (id()), a type (type()), and a value. When you write x = 42, Python creates an int object and binds the name "x" to it.

⚠️ Common Mistake: Mutable Default Arguments

Wrong:

def add_item(item, lst=[]):
    lst.append(item)
    return lst

print(add_item("a"))  # ['a']
print(add_item("b"))  # ['a', 'b'] — Bug!

Why: Default mutable arguments are created once and shared across all calls.

Instead:

def add_item(item, lst=None):
    if lst is None:
        lst = []
    lst.append(item)
    return lst

Quick Reference

TypeExampleNotes
int42, 10**100Unlimited precision
float3.14, 2.998e864-bit IEEE 754
str"hello", f"{x}"Immutable, Unicode
boolTrue, FalseSubclass of int
NoneTypeNoneCheck with is