Variables and assignment

A variable is a name that refers to an object in memory. In many languages a variable is described as a box that holds a value. In Python the better picture is a label: the value lives on its own, and the name is tied to it.

You create a variable with an assignment statement: a name, an equals sign and an expression. Python first evaluates the right-hand side, then binds the name on the left to the result. There is no separate declaration step — the first assignment creates the name.

city = "Lisbon"
temperature = 21
temperature = temperature + 3   # evaluate the right side, then rebind the name
print(city, temperature)
Lisbon 24

The third line is not an equation. It reads "take the current value of temperature, add 3, and let temperature refer to the result". Using a name before anything is assigned to it raises a NameError.

Multiple assignment

One statement can bind several names. Chained assignment gives several names the same object; tuple-style assignment gives each name its own value, pairing them up from left to right.

low = high = 0            # both names refer to the same object
width, height = 1920, 1080  # one value per name
print(low, high, width, height)

a, b = 1, 2
a, b = b, a               # swap: the right side is evaluated first
print(a, b)
0 0 1920 1080
2 1

The number of names must match the number of values, otherwise Python raises a ValueError. This mechanism is called unpacking and works with any iterable (such as a list, a string or a range); see Lists and Tuples.

Naming rules

A variable name is an identifier: a name for a variable, function, class or module. Python accepts an identifier only when it follows these rules:

  • It consists of letters, digits and underscores (_). Letters from other alphabets are allowed too, such as café.
  • It does not start with a digit.
  • It is not a keyword, such as if, class or None.
  • It contains no spaces, hyphens or other punctuation.

Identifiers are case-sensitive: price, Price and PRICE are three different names.

price = 10
Price = 20
_total = price + Price
item2 = "pen"
print(price, Price, _total, item2)
10 20 30 pen

Names such as 2nd_item, first-name, my var and for are all a SyntaxError. By convention, variable names use lowercase words joined by underscores (max_speed), and constants use capitals (MAX_SPEED); see Code Style and Good Habits.

Objects: identity, type and value

Every piece of data in Python is an object: a number, a string, a list and even a function. Each object has three properties:

  • an identity, which never changes while the object exists — id(x) returns it as a number;
  • a type, which decides what you can do with it — type(x) returns it;
  • a value, the data it represents.
score = 42
best = score                  # a second name for the same object
print(type(score))
print(id(score) == id(best))  # same identity: one object, two names

score = score + 1             # score now refers to a different object
print(score, best)
print(id(score) == id(best))
<class 'int'>
True
43 42
False

Assignment never copies an object. best = score makes best refer to the object score refers to. Adding 1 gives a different integer object and rebinds score; best still refers to the old one. The actual numbers id() returns differ from run to run, so compare them rather than print them.

Data types and literals

A data type (or just type) is a kind of value, together with the operations that make sense for it: you can divide numbers but not text, and you can make text uppercase but not numbers. These are the basic built-in types:

  • int — whole numbers: 0, -17, 1_000_000
  • float — numbers with a fractional part: 3.14, -0.5, 2e3
  • bool — truth values: True, False
  • str — text: "Ada", 'x', ""
  • NoneType — "no value": None

The examples after each type are literals: values written directly in the source code. 42 is an integer literal; "42" is a string literal. They look alike but are different types, and that difference matters:

print(type(42))
print(type("42"))
print(42 * 2)
print("42" * 2)
<class 'int'>
<class 'str'>
84
4242

Strings in brief

A string is text between quotes. Single and double quotes are equivalent, so 'Ada' and "Ada" are the same value. Strings have their own page: Strings covers indexing, slicing, methods and formatting.

Numbers: int and float

Integers

An integer (type int) is a whole number, positive, negative or zero. Python integers have no fixed size: they grow as large as memory allows, so they never overflow the way integers do in C or Java. One limit applies to text only: since Python 3.11, converting a very large int to a string (for example with str() or print()) is limited to 4300 digits by default. The arithmetic itself is not limited.

population = 8_100_000_000   # underscores only help the reader
print(population)
print(2 ** 100)
8100000000
1267650600228229401496703205376

Integer literals can also be written in other number systems, with a prefix: 0b for binary, 0o for octal and 0x for hexadecimal. The prefix only changes how you write the number; the value is an ordinary int. The functions bin(), oct() and hex() go the other way and return a string.

print(0b1010, 0o17, 0xFF)
print(bin(10), oct(15), hex(255))
10 15 255
0b1010 0o17 0xff

Floats

A float (floating-point number) is a number with a fractional part, stored in binary with about 15 to 17 significant decimal digits of precision. Any literal with a decimal point is a float, even 5.0. For very large or very small numbers you can use scientific notation: e means "times ten to the power of".

print(5.0, .5, 5.)
print(1.5e3)       # 1.5 × 10³
print(2.5e-4)      # 2.5 × 10⁻⁴
print(1e16)        # large floats are printed in scientific notation
print(10 / 2)      # dividing with / always gives a float
5.0 0.5 5.0
1500.0
0.00025
1e+16
5.0

A literal in scientific notation is always a float, even 1e3, which prints as 1000.0.

Float precision

Most decimal fractions, such as 0.1, have no exact binary form, just as 1/3 has no exact decimal form. A float stores the nearest value it can, and the tiny errors can show up in results:

import math

total = 0.1 + 0.2
print(total)
print(total == 0.3)
print(round(total, 2))
print(math.isclose(total, 0.3))
0.30000000000000004
False
0.3
True

Booleans

A Boolean (type bool) is a truth value: True or False, always with a capital letter. Comparisons produce Booleans, and if statements and while loops use them to decide what to do.

bool is a subtype of int: True behaves as 1 and False as 0 in arithmetic.

is_open = 9 <= 14 < 17   # a comparison gives a bool
print(is_open, type(is_open))
print(True + True)
print(isinstance(True, int))
True <class 'bool'>
2
True

Every object also has a truth value when Python needs one: zero, empty strings and empty collections count as false, almost everything else as true. See Control Flow for these truthy and falsy values.

None

None is Python's value for "nothing here": no result, no answer yet, not applicable. It is the only value of its type, NoneType. A function that does not return anything returns None — even print():

middle_name = None
print(middle_name, type(middle_name))

result = print("Saved")   # print() shows text, but returns None
print(result)
print(middle_name is None)
None <class 'NoneType'>
Saved
None
True

Because there is exactly one None object, the usual test is x is None rather than x == None. None is not the same as 0, False or an empty string, although it counts as false in a condition.

Dynamic typing

Python uses dynamic typing: the type belongs to the object, not to the name. A variable is not declared with a type, and the same name can refer to an int now and a str later. Python checks whether an operation fits the types involved only when that line runs.

reading = 21
print(type(reading))
reading = "21 °C"
print(type(reading))

print(isinstance(reading, str))
print(isinstance(3.5, (int, float)))   # a tuple of types: any of them
<class 'int'>
<class 'str'>
True
True

isinstance(x, T) is the preferred way to test a type in a program, because it also accepts subtypes: isinstance(True, int) is True, while type(True) == int is False.

Dynamic does not mean anything goes. Python is also strongly typed: it does not silently convert between unrelated types. Adding a number to a string is an error, not a guess:

age = 36
print("Age: " + age)
TypeError: can only concatenate str (not "int") to str

Converting between types

To change a value's type, call the type as a function. The result is a new object; the original is unchanged.

print("Age: " + str(36))
print(int("42") + 1)
print(float(7))
print(int(3.9))        # int() cuts off the fraction; it does not round
print(bool(0), bool("False"))
Age: 36
43
7.0
3
False True

Note the last line: bool() of any non-empty string is True, even the string "False". Input and Output shows type conversion on user input, including what happens when the text is not a valid number.