❤️
10 Variables
Variables are used to store data in memory during program execution. They hold values that can be manipulated and changed as needed.
In this chapter, you will learn about variables, data types, naming conventions, and scope in Python.
10.1 Assigning Values to Variables
In Python, variables are initialized/created when you assign a value to them. An assignment statement consists of a variable name, an equal sign (=
, the assignment operator), and the value to be assigned. For example:
counter
, max_temperature
, msg
, and is_raining
are assigned an integer, float, string, and boolean value, respectively.
In Listing 10.1, three assignment statements are shown. In each statement, a value is assigned to a variable. The variable name is on the left side of the assignment operator (=
), and the value to be assigned is on the right side. The variable name can be any valid identifier (a name that follows the rules for naming variables in Python).
Internally, the variable names are references to memory locations where the values are stored. You can think of a variable as a label or name that points to a specific location in memory where the value is stored.
Unlike some other languages, in Python you do not need to declare the variable type explicitly; Python is dynamically typed (i.e., the type of a variable is inferred from the value assigned to it). This means you can assign a value of any type to a variable, and Python will automatically determine the type. Therefore, in Listing 10.1, the variable counter
is assigned an integer value, so it is inferred to be of type int
, the variable max_temperature
is assigned a floating-point value, so it is inferred to be of type float
, and so on.
10.2 Literals
The values assigned to variables are called literals. A literal is a fixed value (i.e., not a variable) that is directly written in the code. For example, in Listing 10.1, 0
, 25.5
, and "Hello, World!"
are literals. Literals can be of different types, such as integers, floating-point numbers, strings, and more.
10.3 Expressions
An expression is a combination of values, variables, and operators that evaluates to a single value. For example, in Listing 10.2, the expression current_capacity / max_capacity * 100
will be evaluated to a single value before being assigned to the variable occupation_rate
. First, the division current_capacity / max_capacity
is performed, and then the result is multiplied by 100
.
10.4 Is x
equal to x + 1
?
Unlike in mathematics, where x = x + 1
is a contradiction, in programming, x = x + 1
is a valid assignment statement.
When you write x = x + 1
in a programming language, you are not stating that x
is equal to x + 1
. Instead, you are updating the value of x
by adding 1
to its current value.
For example:
In this code snippet, the following steps occur:
- The value
5
is assigned to the variablex
. - The expression
x + 1
is evaluated.- The current value of
x
is5
. 5 + 1
is6
.
- The current value of
- The result
6
is assigned back to the variablex
. - The value of
x
is printed, which is6
.

x
equal to x + 1
? In programming, x = x + 1
is a valid assignment statement that updates the value of x
by adding 1
to its current value.
10.5 Overwriting Variables
You can change the value of a variable by assigning a new value to it. The new value can be of the same type or a different type. For example, in Listing 10.3, the variable value
is first assigned the integer value 10
. Then, it is reassigned the string value "Hello"
. The variable value
is overwritten with a new value of a different type.
10.6 Swapping Variable Values
In programming languages it is common to swap the values of two variables. For example, in some applications, you may need to swap the values of two variables to rearrange data or perform certain operations. In Listing 10.4, we present two ways to swap the values of two variables a
and b
in Python. The first method (Listing 10.4 (a)) uses a temporary variable temp
to store the value of a
before swapping. This is a typical approach used in many programming languages. The second method (Listing 10.4 (b)) is a more Pythonic way to swap variables without using a temporary variable. This method uses tuple unpacking to swap the values of a
and b
in a single line.
a
will have the value 10
and b
will have the value 5
.
The term Pythonic refers to code that follows the idiomatic style and best practices of the Python language. Python emphasizes readability and simplicity, and Pythonic code is concise, clear, and easy to understand.
10.7 Naming Conventions
Python has the following naming restrictions for variables:
- Variable names can only contain letters (a-z, A-Z), digits (0-9), and underscores (
_
). For example,$total
,min value
, andtotal-score
are not valid variable names. - Variable names cannot start with a digit. For example,
1st_place
is not a valid variable name.
To make your code more readable and maintainable, it’s important to follow naming conventions. Here are some common naming conventions in Python:
- Use
snake_case
for variable names: Start with a lowercase letter and use underscores to separate words. For example:student_name
student_age
total_score
is_passed
max_value
- Use uppercase letters for constants: Use all uppercase letters with underscores to separate words. For example,
MAX_VALUE
,PI
. - Use descriptive names: Choose names that describe the purpose of the variable. For example:
student_name
instead ofname
student_age
instead ofage
MAX_SCORE
instead ofmax
- Avoid reserved words: Don’t use reserved words or keywords as variable names. For example:
def
,class
,if
,else
,return
,for
,while
, etc. are reserved words in Python.
- Avoid abbreviations: Use full words instead of abbreviations to make the code more readable. For example:
student_name
instead ofstd_name
student_age
instead ofs_age
calculate_total_lateness
instead ofcalculate_tl
In Python, variable names are case-sensitive. For example, studentName
and StudentName
are considered two different variables. It’s important to be consistent with the naming conventions to avoid confusion.
10.8 Data Types
Python supports various data types that can be used to store different kinds of data. Since Python is dynamically typed, the type of a variable is determined at runtime based on the value assigned.
Some of the basic data types in Python include:
- Numeric Types:
int
: Represents integers. Examples:25
,-10
,0
.float
: Represents floating-point numbers. Examples:3.14
,2.5
,-0.75
.
- Boolean Type:
bool
: RepresentsTrue
orFalse
.
- Sequence Types:
str
: Represents strings (text). Values are enclosed in quotes ('
or"
). Examples:"Hello"
,'Python'
.
Throughout this course, you will encounter other data types:
- Sequence Types:
list
: Represents ordered, mutable collections. Examples:[1, 2, 3]
,['apple', 'banana', 'cherry']
.tuple
: Represents ordered, immutable collections. Examples:(1, 2, 3)
,('apple', 'banana', 'cherry')
.
- None Type:
NoneType
: Represents the absence of a value,None
.
- Mapping Type:
dict
: Represents unordered collections of key-value pairs. Examples:{'name': 'Alice', 'age': 25}
,{1: 'apple', 2: 'banana'}
.
- Set Types:
set
: Represents unordered collections of unique elements. Examples:{1, 2, 3}
,{'apple', 'banana', 'cherry'}
.frozenset
: Immutable version ofset
. Examples:frozenset({1, 2, 3})
,frozenset({'apple', 'banana', 'cherry'})
.
10.8.1 Numeric Data Types
Typically, numeric data types (in several programming languages) are referred to as:
- Integer:
- Whole numbers without any fractional or decimal part (e.g.,
0
,1
,-10
). - Can be both positive and negative numbers or zero.
- Typically used for counting, indexing, and situations where exact whole numbers are required.
- Whole numbers without any fractional or decimal part (e.g.,
- Floating-Point:
- Feature a decimal point (e.g.,
3.14
,2.5
,-0.75
). - Represents real numbers (integers and numbers with fractional parts).
- Used when you need to represent a wider range of values with varying degrees of precision.
- Can represent very large or very small numbers using scientific notation (e.g.,
1.23e-4
).
- Feature a decimal point (e.g.,
The term “floating-point” refers to the fact that the decimal point can “float” to the left or right, allowing the representation of both very large and very small numbers.
10.8.1.1 Writing Numeric Literals
Numeric literals can be written in different formats:
- Integer Literals:
- Can be written in decimal (base 10) format (e.g.,
10
,100
,-5
). - Can also be written in binary (base 2) format by prefixing with
0b
or0B
(e.g.,0b1010
,0B1101
). - Can be written in octal (base 8) format by prefixing with
0o
or0O
(e.g.,0o12
,0O17
). - Can be written in hexadecimal (base 16) format by prefixing with
0x
or0X
(e.g.,0x1A
,0XFF
). Hexadecimal numbers use the digits0-9
andA-F
(ora-f
) to represent values10-15
. - Can include underscores (
_
) to improve readability (e.g.,1_000_000
,0b1101_1010
,0x1A_BF
).Underscores are ignored by the Python interpreter and are used to separate groups of digits for better readability.
- Can be written in decimal (base 10) format (e.g.,
- Floating-Point Literals:
- Can be written in decimal format with a decimal point (e.g.,
3.14
,2.5
,-0.75
). - Can use scientific notation to represent very large or very small numbers (e.g.,
1.23e-4
,2.5e6
). - Can include underscores (
_
) for better readability (e.g.,3.14_159
,1.23e-4
,300_000.0
). - Can also be written as integers with a decimal point (e.g.,
10.0
,-5.0
). These are still considered floating-point numbers.
- Can be written in decimal format with a decimal point (e.g.,
Here’s the revised section with corrections, clarifications, and the use of an appropriate table to illustrate numeric literals and their behavior:
10.8.2 Dealing with Very Large or Very Small Numbers
Floating-point numbers can represent very large or very small numbers using the scientific notation. For instance:
1.23e-4
represents \(1.23 \times 10^{-4}\), or0.000123
.2.5e6
represents \(2.5 \times 10^6\), or2,500,000
.
However, floating-point numbers have limitations due to how they are represented in memory. They allocate a fixed number of bits for the mantissa and exponent, which can result in:
- Rounding errors when precision exceeds the allocated bits.
- Overflow when values exceed the representable range.
- Underflow when values are too close to zero to be represented accurately.
For precise calculations involving extremely large or small numbers, consider using libraries such as decimal
(for arbitrary precision) and numpy
(for numerical computing). In Table 10.1, we illustrate the behavior of floating-point literals in Python.
Literal | Expected Value | Python Evaluation |
---|---|---|
1.79e308 |
\(1.79 \times 10^{308}\) | 1.79e+308 |
1.8e308 |
\(1.8 \times 10^{308}\) | inf (overflow) |
5.0e-324 |
\(5.0 \times 10^{-324}\) | 5e-324 |
1.0e-325 |
\(1.0 \times 10^{-325}\) | 0.0 (underflow) |
10.8.3 String Data Type
A string literal, or str
, is a sequence of characters (i.e., letters, numbers, symbols) enclosed either in single quotes ('
) or double quotes ("
). It is how text data is represented in Python. They are referred to as “strings” because they are a sequence of characters strung together. In Python, strings are immutable, meaning they cannot be changed after they are created (you can create a new string based on an existing string, but you cannot modify the original string). In Listing 10.5, some examples of string literals are shown.
In Listing 10.5, the variables name1
and name2
store the string "Alice"
, hello1
and hello2
store strings with quotes inside them, result
stores an empty string, and smiley
stores a string with an emoji. Strings can contain letters, numbers, symbols, whitespace, and special characters. They can also be empty (i.e., contain no characters). Notice that you can use either single or double quotes to create a string, but the opening and closing quotes must match. You can also use single quotes inside double quotes and vice versa.
10.8.3.1 Multiline Strings
A string can also be created using triple quotes ('''
or """
) to span multiple lines:
multiline_str1 = """This is a
multi-line string"""
multiline_str2 = '''This is also a
multi-line string'''
print("""
The
quick brown fox
jumps over the lazy dog.
""")
If you need to include single or double quotes within a string, you can use an escape character (\
) before the quote:
When no text is present in the string, it is referred to as an empty string. An empty string is represented by two quotes with no space between them (""
or ''
).
10.8.3.2 Scaping Characters
Strings sometimes contain special characters, that are not easily visible or printable. These characters are represented using escape sequences. For example, the newline character (\n
) is used to create a new line in a string. In Python, you can use the backslash (\
) as an escape character to include special characters in a string. A scape character is a character that is not normally interpreted by the program but has a special meaning when preceded by a backslash. Some common escape sequences in Python strings are shown in Table 29.10.
Escape Sequence | Description | Example | Result |
---|---|---|---|
\\ |
Backslash | "C:\\Users\\Alice" |
C:\Users\Alice |
\' |
Single quote | 'It\'s raining' |
It's raining |
\" |
Double quote | "She said, \"Hello!\"" |
She said, "Hello!" |
\n |
Newline | "First line\nSecond line" |
|
\t |
Tab | "First\tSecond" |
First Second |
\b |
Backspace | "Hello\bWorld" |
HellWorld |
If you don’t use the escape character, Python will interpret the character literally (e.g., a newline character will be displayed as \n
instead of creating a new line).
10.8.3.3 Multiline Comments
In Python, you can use triple quotes ('''
or """
) to create multiline comments. While Python does not have a built-in syntax for multiline comments, you can use triple quotes to create multiline strings that are not assigned to a variable. These strings are treated as comments and are ignored by the Python interpreter. For example:
It is common to use multiline comments to provide detailed explanations of code, document functions, or add notes to the code. For example, in Listing 10.6, a multiline comment is used to describe the purpose of a function. This is called a docstring (documentation string) and is a common practice in Python to document functions and modules.
convert_to_imperial
using a docstring (documentation string) based on the Numpy Python library style (see Numpy docstring guide).
def convert_to_imperial(height_cm):
'''
Convert height from centimeters to feet and inches.
This function takes the height in centimeters as
input and converts it to feet and inches.
The conversion is based on the following:
1 foot = 30.48 centimeters
1 inch = 2.54 centimeters
The height is converted to feet and inches and
returned as a string in the format "<feet>'<inches>".
Parameters:
----------
height_cm : float
Height in centimeters.
Returns:
-------
str
Height in feet and inches.
Example:
--------
>>> convert_to_imperial(175)
"5'9\""
'''
10.8.3.4 Concatenating Strings
You can concatenate strings using the +
operator. Concatenation is the process of combining two or more strings into a single string. For example:
first_name = "Alice"
last_name = "Smith"
full_name = first_name + " " + last_name
print(full_name) # Output: Alice Smith
In this example, the strings first_name
and last_name
are concatenated with a space in between to create the full_name
string.
10.8.3.5 String Interpolation (f-strings)
Python 3.6 introduced f-strings (formatted string literals) as a new way to format strings. F-strings allow you to embed expressions inside string literals, using curly braces ({}
) to evaluate the expressions and insert their values into the string. In Listing 10.7, an example of using f-strings to format a time string is shown.
hours
, minutes
, and seconds
are embedded inside the string time_str
using curly braces {}
.
The f
before the opening quote indicates that the string is an f-string. Inside the f-string, you can include variables, expressions, and even function calls (i.e., any valid Python expression). The expressions inside the curly braces are evaluated and replaced with their values in the resulting string. Numbers are automatically converted to strings when embedded in an f-string and other objects can be converted to strings using the str()
function. In Table 10.3, we provide examples of using f-strings for string interpolation.
Expression | Description | Input | Result |
---|---|---|---|
f"Hello, {name}!" |
Embedding a variable | name = "Alice" |
"Hello, Alice!" |
f"Total: {price * quantity}" |
Embedding an expression | price = 20 , quantity = 5 |
"Total: 100" |
f"Today is {datetime.now():%A, %B %d, %Y}" |
Embedding a function call | datetime.now() = datetime(2022, 1, 1) |
"Today is Saturday, January 01, 2022" |
f"Value: {value:.2f}" |
Formatting a floating-point number | value = 10.5 |
"Value: 10.50" |
f"Count: {count:04d}" |
Formatting an integer with leading zeros | count = 10 |
"Count: 0010" |
f"Name: {name.upper()}" |
Calling a method on a string | name = "Alice" |
"Name: ALICE" |
f"Title: {title:^20}" |
Centering a string within a width of 20 | title = "My Title" |
" My Title " |
f"Items: {', '.join(items):<20}" |
Joining a list and left-justifying within a width of 20 | items = ["item1", "item2"] |
"Items: item1, item2 " |
f"Total: {total:,.2f}" |
Formatting a number with commas as thousands separators | total = 1000 |
"Total: 1,000.00" |
f"Percentage: {percentage:.2%}" |
Formatting a number as a percentage | percentage = 0.5 |
"Percentage: 50.00%" |
f"Binary: {num:b}" |
Formatting an integer as binary | num = 10 |
"Binary: 1010" |
f"Right-aligned: {value:>10}" |
Right-aligning a string within a width of 10 | value = "value" |
"Right-aligned: value" |
10.8.3.6 Useful String Methods
Python provides several built-in methods to manipulate strings. In Table 29.11, some common string methods are listed. These methods can be used to convert strings to uppercase or lowercase, strip whitespace, split strings, find substrings, replace text, and more.
Method | Description | Example | Result |
---|---|---|---|
upper() |
Converts the string to uppercase | "hello".upper() |
"HELLO" |
lower() |
Converts the string to lowercase | "Hello".lower() |
"hello" |
capitalize() |
Converts the first character to uppercase | "hello".capitalize() |
"Hello" |
title() |
Converts the first character of each word to uppercase | "hello world".title() |
"Hello World" |
strip() |
Removes leading and trailing whitespace | " hello ".strip() |
"hello" |
lstrip() |
Removes leading whitespace | " hello ".lstrip() |
"hello " |
rstrip() |
Removes trailing whitespace | " hello ".rstrip() |
" hello" |
center() |
Centers the string within a specified width | "hello".center(10) |
" hello " |
ljust() |
Left-justifies the string within a specified width | "hello".ljust(10) |
"hello " |
rjust() |
Right-justifies the string within a specified width | "hello".rjust(10) |
" hello" |
ord() |
Returns the Unicode code point of a character | ord("A") |
65 |
chr() |
Returns the character from a Unicode code point | chr(65) |
"A" |
split() |
Splits the string into a list of substrings | "hello world".split() |
["hello", "world"] |
partition() |
Splits the string at the first occurrence of a separator | "hello world".partition(" ") |
("hello", " ", "world") |
join() |
Joins a list of strings into a single string | " ".join(["hello", "world"]) |
"hello world" |
startswith() |
Checks if the string starts with a specified substring | "hello".startswith("he") |
True |
endswith() |
Checks if the string ends with a specified substring | "hello".endswith("lo") |
True |
find() |
Searches for a substring and returns its index | "hello".find("l") |
2 |
replace() |
Replaces a substring with another string | "hello".replace("e", "a") |
"hallo" |
index() |
Searches for a substring and returns its index | "hello".index("l") |
2 |
count() |
Counts the occurrences of a substring | "hello".count("l") |
2 |
len() |
Returns the length of the string | len("hello") |
5 |
isalpha() |
Checks if all characters are alphabetic | "hello".isalpha() |
True |
isdigit() |
Checks if all characters are digits | "123".isdigit() |
True |
isalnum() |
Checks if all characters are alphanumeric | "hello123".isalnum() |
True |
isspace() |
Checks if all characters are whitespace | " ".isspace() |
True |
istitle() |
Checks if the string is titlecased | "Hello World".istitle() |
True |
isupper() |
Checks if all characters are uppercase | "HELLO".isupper() |
True |
islower() |
Checks if all characters are lowercase | "hello".islower() |
True |
In Python, strings are represented using Unicode characters. Unicode is a standard for encoding characters from different writing systems. Each character is assigned a unique code point, which is an integer value that represents the character. The ord()
function returns the Unicode code point of a character, and the chr()
function returns the character from a Unicode code point.
Even emojis and special characters can be represented using Unicode characters. For example, the Unicode code point for the heart emoji ❤️ is U+2764
. In Listing 10.8, the heart emoji is represented using its Unicode code point.
U+2764
.
10.8.4 String Indexing and Slicing
Strings can be broken down into individual characters using indexing. In Python, strings are zero-indexed, meaning the first character is at index 0
, the second character is at index 1
, and so on. You can access individual characters in a string using square brackets ([]
) with the index of the character you want to access. For example, in Table 10.5, the string "Python"
is indexed using different positive and negative indices.
String | P | y | t | h | o | n |
---|---|---|---|---|---|---|
Positive Index | 0 | 1 | 2 | 3 | 4 | 5 |
Negative Index | -6 | -5 | -4 | -3 | -2 | -1 |
To access a character at a specific index, you can use the index inside square brackets. In Table 29.8, we provide examples of accessing characters in a string variable named s
whose value is "Python"
.
s = "Python"
.
Expression | Description | Result |
---|---|---|
s[0] |
Access the first character | "P" |
s[3] |
Access the fourth character | "h" |
s[-1] |
Access the last character | "n" |
s[-3] |
Access the third character from the end | "h" |
s[6] |
Accessing an out-of-range index | Raises an IndexError |
s[-1] |
Accessing an out-of-range negative index | Raises an IndexError |
You can also extract a substring from a string using slicing. Slicing allows you to create a substring by specifying a range of indices. The syntax for slicing is s[start:end]
, where start
is the starting index (inclusive) and end
is the ending index (exclusive). If start
is not specified, it defaults to 0
, and if end
is not specified, it defaults to the end of the string. A third parameter, called the step, can also be specified as s[start:end:step]
to extract every step
-th character. In Table 29.9, we provide examples of slicing the string "Python"
to extract substrings.
s = "Python"
.
Expression | Description | Result |
---|---|---|
s[:] |
Slicing to get the entire string | "Python" |
s[0:2] |
Slicing to get a substring | "Py" |
s[2:5] |
Slicing to get a substring | "tho" |
s[:4] |
Slicing from the beginning | "Pyth" |
s[3:] |
Slicing to the end | "hon" |
s[-4:-1] |
Slicing with negative indices | "tho" |
s[::-1] |
Reverse the string | "nohtyP" |
s[::2] |
Get every second character | "Pto" |
s[1::2] |
Get every second character starting from the second character | "yhn" |
s[1:4:2] |
Get every second character from the second to the fourth character | "yh" |
s[4:1:-1] |
Reverse a substring | "oht" |
10.8.5 Breaking Long String Lines
When writing long strings that span multiple lines, you can use parentheses ()
to break the string into multiple lines. This is useful for improving code readability and maintaining a consistent line length. For example, in Listing 10.9, a long string is broken into multiple lines using parentheses.
long_str = ("This is a long string that spans multiple lines. "
"It is enclosed in parentheses to break it into "
"multiple lines for better readability.")
print(long_str)
This is a long string that spans multiple lines. It is enclosed in parentheses to break it into multiple lines for better readability.
In Listing 10.9, the long string is enclosed in parentheses, and each line is separated by a space. When the code is executed, the long string is printed as a single line, even though it is written across multiple lines in the code.
10.8.6 Boolean Data Type
Boolean data types represent logical values: True
or False
.
10.9 Type Conversion
Sometimes, you may need to convert a value from one data type to another. This can be done using built-in functions.
For example:
# Convert string to integer
age_str = "25"
age_int = int(age_str) # Now age_int is an integer 25
# Convert integer to string
score = 95
score_str = str(score) # Now score_str is the string "95"
# Convert string to float
height_str = "1.75"
height_float = float(height_str) # Now height_float is 1.75
# Convert integer to float
count = 10
count_float = float(count) # Now count_float is 10.0
If you try to convert incompatible types, Python will raise a ValueError
:
10.10 Constants
Python does not have built-in constant types or keywords to declare constants. However, by convention, variables that should not change are written in uppercase letters. This is a way to signal to other developers that the value should be treated as a constant.
For example:
While Python does not enforce immutability of these variables, using uppercase names helps indicate that they are intended to be constants.
Using constants in your Python code has several advantages:
- Improved Code Readability: Constants make your code more readable by providing meaningful names for values that are used multiple times.
- Higher Flexibility: If the value of a constant changes, you only need to modify it in one place, rather than searching for and updating multiple occurrences of the value throughout your code. This makes your code easier to maintain and less error-prone.
10.10.1 Example: Converting Measurements Using Constants
Here’s an example of using constants to convert measurements from metric to imperial units:
FEET_TO_CENTIMETERS = 30.48
FEET_TO_INCHES = 12
def convert_to_imperial():
height_in_centimeters = float(input("Enter height in centimeters: "))
feet = int(height_in_centimeters / FEET_TO_CENTIMETERS)
inches = ((height_in_centimeters / FEET_TO_CENTIMETERS) - feet) * FEET_TO_INCHES
height_in_feet_and_inches = f"{feet}'{round(inches)}\""
print("Height in feet and inches:", height_in_feet_and_inches)
# Example usage
convert_to_imperial()
In this example, the user is prompted to enter a height in centimeters, which is then converted to feet and inches using the constants FEET_TO_CENTIMETERS
and FEET_TO_INCHES
. The result is displayed in the format <feet>'<inches>"
.