Skip to content
elephantoo

Variables & data types

Lesson 2 of 38 13 min read

Dynamic typing, naming rules, core built-in types, None, type conversion and how names reference objects.


Every program works with data: names, prices, dates, yes/no answers. In Python you give data a name with a variable, and every piece of data has a type that decides what you can do with it. This lesson builds the mental model you'll rely on for the rest of the course.

Creating variables#

A variable is created the first time you assign to it with =:

Python
course = "Python"
lessons = 38
rating = 4.9
is_free = True

print(course, lessons, rating, is_free)
Output
Python 38 4.9 True

There is no let, var or type declaration. Read lessons = 38 as "make the name lessons refer to the value 38". You can reassign a name at any time, even to a different type:

Python
answer = 42
answer = "forty-two"   # allowed: the name now points at a str
print(answer)
Output
forty-two

That's what dynamically typed means: the type belongs to the value, not to the name. It's flexible, but it means you must keep track of what each name holds — good names help a lot.

Naming rules and conventions

  • Names can contain letters, digits and underscores, but can't start with a digit: total_2, not 2total.
  • They are case-sensitive: score and Score are different.
  • You can't use keywords like if, for, class, def, None.
  • Convention (PEP 8): snake_case for variables and functions, UPPER_CASE for constants, PascalCase for classes.
Python
MAX_RETRIES = 3            # a "constant" — Python won't stop you changing it,
user_name = "ada_l"        # but the capitals tell other developers not to

Prefer descriptive names (unit_price, retry_count) over cryptic ones (up, x2).

The core built-in types#

TypeExampleUsed for
int42, -7, 1_000_000whole numbers (unlimited size)
float3.14, 2.5e-3numbers with a fractional part
str"hello", 'hi'text
boolTrue, Falseyes/no values
NoneTypeNone"no value here"
list[1, 2, 3]ordered, changeable collections
tuple(3, 4)ordered, fixed collections
dict{"name": "Ada"}key → value lookups
set{1, 2, 3}unique items

You'll get a full lesson on each collection type. For now, use type() to ask any value what it is:

Python
print(type(42))
print(type(3.14))
print(type("hi"))
print(type(True))
print(type(None))
print(type([1, 2]))
print(type({"a": 1}))
Output
<class 'int'>
<class 'float'>
<class 'str'>
<class 'bool'>
<class 'NoneType'>
<class 'list'>
<class 'dict'>

In real code, prefer isinstance() for checks, because it also accepts subclasses and several types at once:

Python
value = 7.5
print(isinstance(value, float))
print(isinstance(value, (int, float)))   # "is it any kind of number?"
Output
True
True

None: the absence of a value#

None is Python's way of saying "nothing yet" or "not applicable". Functions that don't return anything return None, and it's common as a placeholder:

Python
middle_name = None

if middle_name is None:
    print("No middle name")
Output
No middle name

Always compare with is None / is not None rather than == None.

Converting between types#

Values don't change type on their own — Python won't silently turn "5" into 5. You convert explicitly with the type's name:

Python
print(int("42") + 1)       # str -> int
print(float("3.5") * 2)    # str -> float
print(str(99) + " bottles")# int -> str
print(int(7.9))            # float -> int truncates toward zero
print(round(7.9))          # round() rounds to the nearest int
print(bool(0), bool(""), bool("no"))
Output
43
7.0
99 bottles
7
8
False False True

int("3.7") and int("abc") raise ValueError. When converting user input you'll handle that with try/except (covered in the exceptions lesson).

The last line hints at truthiness: every value can act as a boolean. 0, 0.0, "", [], {}, set() and None are falsy; almost everything else is truthy. You'll use this constantly in if statements.

Multiple assignment and swapping#

Python
x, y, z = 1, 2, 3          # unpack three values into three names
a = b = 0                  # both names point to the same 0
x, y = y, x                # swap without a temporary variable
print(x, y, z, a, b)
Output
2 1 3 0 0

Names are labels, not boxes#

This is the most important idea in the lesson. A variable is a label attached to an object, not a box that holds a copy. Assignment attaches another label; it never copies:

Python
a = [1, 2]
b = a            # b is another label on the SAME list
b.append(3)
print(a)
print(a is b)    # `is` checks "same object?"
print(id(a) == id(b))
Output
[1, 2, 3]
True
True

With immutable types (int, float, str, bool, tuple, None) this never surprises you, because those objects can't change — any "change" creates a new object:

Python
s = "hi"
t = s
t = t + "!"      # creates a NEW string; s is untouched
print(s, t)
Output
hi hi!

With mutable types (list, dict, set, most custom objects), several names can see the same change. When you really want an independent copy, ask for one: b = a.copy() or b = list(a).

Common mistakes#

  • Mixing text and numbers: "Age: " + 30 is a TypeError. Use str(30) or, better, an f-string: f"Age: {30}".
  • Using = when you mean ==: = assigns, == compares. if x = 5: is a syntax error.
  • Shadowing built-ins: naming a variable list, str, input or sum hides the built-in function, and later calls like list(...) break mysteriously.
  • Assuming assignment copies: it doesn't — see "Names are labels" above.

What's next#

You know how to name values and inspect their types. Next we'll dig into the first family of values properly: numbers and operators, including the division gotchas every beginner trips over.

Check your understanding

Quick quiz

0/3 answered
  1. 1.What does type(3.14) return?

  2. 2.After a = [1, 2], b = a, b.append(3), what is a?

  3. 3.What is the result of int("3.7")?

Finished reading?

Mark this lesson complete to track your progress.