Skip to content

Introduction to Python

Part 2 · Programming languages · Chapter 7 · Lecture notes, volume 2 (PDF) · Exercises: Introduction to Python

Introduction

In the chapter «Introduction to C++» we translated the pseudo-code of our algorithms into a compiled programming language. In this chapter we introduce a second programming language, Python, which is interpreted, has a lighter syntax and is very popular both in teaching and in scientific computing.

The chapter follows the same path as the chapter «Introduction to C++», so that the two languages can be compared section by section:

  • the main characteristics of the language and the structure of a program;

  • variables, data types, input and output;

  • operators, conditional statements and loops;

  • lists, which play the role of the arrays of C++;

  • functions, their parameters and their return values;

  • a complete algorithm, the search of the maximum value in an array, written in pseudo-code and in Python;

  • the bitwise operators and a summary table that compares Python with C++.

Every fragment of code of the chapter has been executed with the python3 interpreter (Python 3.14): the outputs reported in the examples are the ones printed by the programs.

In pseudo-code the entries of an array \(a[1..n]\) are indexed from \(1\) to \(n\); in Python, as in C++, the elements of a list of size \(n\) are indexed from \(0\) to \(n-1\). The entry \(a[i]\) of the pseudo-code corresponds to the element a[i-1] of the Python code.

7.1 Main characteristics of the programming language

The main characteristics of Python are the following.

  • Python is an interpreted language: programs are executed instruction by instruction by the Python interpreter, without a separate compilation step. This makes development and debugging fast and interactive.

  • Python uses dynamic typing: variables do not need to be declared with a data type. The data type is determined automatically, during the execution, from the assigned value.

  • Python supports functions, enabling a structured and modular approach to programming. Functions allow code reuse and better organization.

  • Indentation is mandatory in Python: the block structure of the code (loops, conditional statements, functions) is defined by the level of indentation, not by curly braces. The standard indentation is \(4\) spaces.

  • In Python, a single-line comment starts with the reserved symbol “#”. There is no dedicated symbol for multi-line comments: a text enclosed between triple quotes """ (or ”') is a string that is not used by the program, and it is commonly used as a multi-line comment. The same string written as the first line of a function is its documentation string (docstring).

Example 7.1: comments in Python

This is an example of a single-line comment:

# This is a comment line

This is an example of a multi-line comment:

"""
This is a
multi-line comment
"""

7.1.1 The structure of a program

A Python program is a text file (with extension .py) that is executed by the interpreter from the first line to the last one. Unlike C++, no main function is required: the instructions written at the top level of the file are executed in order.

Example 7.2: the skeleton of a program

# The instructions of the program are written here
print("Hello, world!")

If the source code is saved in the file hello.py, it is executed with the command

python3 hello.py

and the output is

Hello, world!

In the following examples, unless they contain a complete program, the fragments of code are written at the top level of a file and executed in this way.

  • A block of instructions (the body of a conditional statement, of a loop or of a function) is introduced by the symbol “:” at the end of the preceding line, and all its instructions are indented by the same number of spaces. The block ends at the first instruction that is indented less.

Example 7.3: blocks defined by indentation

x = 7
if x > 0:
    print("positive")        # Inside the block of the if
    print("still inside")    # Inside the block of the if
print("outside the block")   # Executed in any case

Output:

positive
still inside
outside the block

In C++ the same block would be enclosed in curly braces {}; in Python a wrong indentation changes the meaning of the program or produces an IndentationError.

In Python the instructions do not end with “;”, and the blocks are delimited by the indentation (4 spaces) instead of curly braces.

7.2 Variables and data types

The source code operates on variables, and every value has a data type.

  • Information is categorized into different data types. The four fundamental data types are:

    1. The data type “int” represents an integer, which is a whole number written without a decimal point. This includes positive and negative whole numbers, as well as zero. Unlike C++, the integers of Python have no maximum value: they can have as many digits as needed.

    2. The data type “bool” represents a Boolean value: True or False (note the capital first letter).

    3. The data type “float” represents a floating-point number, which includes numbers written with a decimal point. A float of Python has the same (double) precision as a double of C++.

    4. The data type “str” represents a string of characters, enclosed in single or double quotes (e.g., 'hello', "world"). There is no separate data type for a single character: a character is a string of length \(1\).

  • A variable acts as a container that stores a value. Each variable has a unique name.

  • Variables are assigned values using the assignment operator “=”. When a new value is assigned, the previous value is overwritten.

  • No declaration is needed before use: a variable is created the moment a value is assigned to it. The function type() returns the data type of a value.

Variables are created by assignment; there is no separate declaration step, and the data type is not written in the code.

Example 7.4: variable assignments

age = 25                   # Integer variable
is_raining = False         # Boolean variable
small_number = 3.14        # Floating-point variable
large_number = 123456.789  # Floating-point variable
character = 'a'            # String variable (single character)
name = "Alice"             # String variable

age = 26  # The previous value 25 is overwritten
print(age, is_raining, small_number, large_number, character, name)
print(type(age), type(is_raining), type(small_number), type(name))

Output:

26 False 3.14 123456.789 a Alice
<class 'int'> <class 'bool'> <class 'float'> <class 'str'>

Compare with Example 7.6 below and with the corresponding example of the chapter «Introduction to C++»: the Boolean value is displayed as False, and the number 123456.789 is displayed with all its digits.

Example 7.5: dynamic typing and large integers

x = 5
print(x, type(x))
x = "five"  # The same name now refers to a string
print(x, type(x))

print(2 ** 100)  # An integer with 31 digits

Output:

5 <class 'int'>
five <class 'str'>
1267650600228229401496703205376

The operator ** is the exponentiation (Section 7.4.1). In C++ the value \(2^{100}\) does not fit in a variable of type int.

7.3 Input and output

  • The function print() displays output on the screen. Multiple values can be printed in one call by separating them with commas: they are displayed separated by a space, and the line ends with a new line (the same effect as endl in C++).

  • The optional parameters sep and end change the separator between the values and the text written at the end: print(x, end=" ") writes a space instead of a new line, so the next print continues on the same line.

  • Strings and variable values can be combined using f-strings (formatted string literals), prefixed with the letter f. Inside f-strings, variable names (and, more generally, expressions) are placed between curly braces {}.

  • Inside the curly braces of an f-string, the format :.kf displays a floating-point number with exactly \(k\) digits after the decimal point (the same effect as fixed and setprecision(k) in C++).

Example 7.6: screen output

n = 42
print("The value of the variable is", n)
print(f"The value of the variable is {n}")  # f-string version
print(f"n = {n}, doubled = {n * 2}")        # Expression inside {}

print("a", "b", "c", sep="-")   # Separator "-" instead of a space
print("No new line", end=" ")   # A space instead of the new line
print("after end")
print(f"{10 / 3:.2f}")          # Two digits after the decimal point

Output:

The value of the variable is 42
The value of the variable is 42
n = 42, doubled = 84
a-b-c
No new line after end
3.33
  • The function input() displays a message, waits for the user to type a line of text and returns it. It always returns a str; to obtain a number, the result must be converted with int() or float().

Example 7.7: keyboard input

name = input("Enter your name: ")             # Reads a string
n = int(input("Enter an integer: "))          # Reads and converts to int
x = float(input("Enter a real number: "))     # Reads and converts to float
print(f"Hello {name}, n = {n}, x = {x}")

Example of execution (the user types Ada, 7 and 2.5):

Enter your name: Ada
Enter an integer: 7
Enter a real number: 2.5
Hello Ada, n = 7, x = 2.5

7.4 Operators

Operators are symbols that perform operations on variables and values. As in C++, they are classified, according to their functionality, into arithmetic, assignment, comparison and logical operators; Python has no increment and decrement operators.

7.4.1 Arithmetic operators

Arithmetic operators, used to perform basic mathematical operations:

  • + (Addition) \(\rightsquigarrow\) Adds two values.

  • - (Subtraction) \(\rightsquigarrow\) Subtracts one value from another.

  • * (Multiplication) \(\rightsquigarrow\) Multiplies two values.

  • / (Division) \(\rightsquigarrow\) Divides one value by another (always returns a float).

  • // (Integer division) \(\rightsquigarrow\) Returns the integer quotient (floor division).

  • % (Modulus) \(\rightsquigarrow\) Returns the remainder of a division.

  • ** (Exponentiation) \(\rightsquigarrow\) Raises a value to a power.

Example 7.8: arithmetic operators

a = 10
b = 3

print("Addition:", a + b)
print("Subtraction:", a - b)
print("Multiplication:", a * b)
print("Division:", a / b)          # Always a float
print("Integer division:", a // b)
print("Modulus:", a % b)
print("Exponentiation:", a ** b)

Output:

Addition: 13
Subtraction: 7
Multiplication: 30
Division: 3.3333333333333335
Integer division: 3
Modulus: 1
Exponentiation: 1000

The last digit 5 of the division is not an error of the program: \(10/3\) has infinitely many decimal digits, and the float closest to it is displayed.

  • The division operator / always returns a float in Python 3, even when dividing two integers. To obtain an integer result, use the integer division operator //. This is the opposite convention with respect to C++, where 10 / 3 is the integer division.

  • The operator // computes \(\lfloor a/b \rfloor\), rounding down. For non-negative operands it coincides with the integer division of C++; for a negative quotient it does not, because C++ truncates toward zero: in Python -7 // 2 is -4 and -7 % 2 is 1, while in C++ -7 / 2 is -3 and -7 % 2 is -1. In both languages the identity \(a = b \cdot q + r\) holds between quotient \(q\) and remainder \(r\).

  • A value is converted into another data type (type conversion) with the functions int(), float() and str(): int(3.9) is 3 (the decimal part is removed), float(7) is 7.0, int("12") is the integer 12.

Example 7.9: integer and floating-point division

a = 10
b = 3

print(a / b)             # Floating-point division
print(a // b)            # Integer division
print(f"{a / b:.2f}")    # Two decimals
print(-7 // 2, -7 % 2)   # Floor division with a negative quotient
print(int(-7 / 2))       # Truncation toward zero, as in C++
print(int(3.9), float(7), int("12") + 1)

Output:

3.3333333333333335
3
3.33
-4 1
-3
3 7.0 13

7.4.2 Assignment operators

Assignment operators, used to assign values to variables:

  • = (Assignment) \(\rightsquigarrow\) Assigns a value to a variable.

  • += (Addition assignment) \(\rightsquigarrow\) Adds a value and assigns the result.

  • -= (Subtraction assignment) \(\rightsquigarrow\) Subtracts a value and assigns the result.

  • *= (Multiplication assignment) \(\rightsquigarrow\) Multiplies and assigns the result.

  • /= (Division assignment) \(\rightsquigarrow\) Divides and assigns the result (a float).

  • //= (Integer division assignment) \(\rightsquigarrow\) Floor-divides and assigns the result.

  • %= (Modulus assignment) \(\rightsquigarrow\) Applies the modulus and assigns the result.

  • **= (Exponentiation assignment) \(\rightsquigarrow\) Raises to a power and assigns the result.

Example 7.10: assignment operators

x = 10  # Assignment
print("Initial value:", x)

x += 5   # Equivalent to: x = x + 5
print("After += 5:", x)

x -= 3   # Equivalent to: x = x - 3
print("After -= 3:", x)

x *= 2   # Equivalent to: x = x * 2
print("After *= 2:", x)

x //= 4  # Equivalent to: x = x // 4
print("After //= 4:", x)

x %= 4   # Equivalent to: x = x % 4
print("After %= 4:", x)

x **= 3  # Equivalent to: x = x ** 3
print("After **= 3:", x)

x /= 4   # Equivalent to: x = x / 4 (the result is a float)
print("After /= 4:", x)

Output:

Initial value: 10
After += 5: 15
After -= 3: 12
After *= 2: 24
After //= 4: 6
After %= 4: 2
After **= 3: 8
After /= 4: 2.0

7.4.3 Increment and decrement

  • Python has no operators ++ and - -: a variable is incremented with x += 1 and decremented with x -= 1.

  • The instruction x++ is a syntax error. The expression ++x is accepted, but it does not increment x: it applies twice the unary plus, so its value is x itself.

Example 7.11: increment and decrement

x = 5
x += 1          # Increment
print("After x += 1:", x)
x -= 1          # Decrement
print("After x -= 1:", x)
print("++x is", ++x, "and x is still", x)  # ++x is not an increment

Output:

After x += 1: 6
After x -= 1: 5
++x is 5 and x is still 5

7.4.4 Comparison operators

Comparison operators, used to compare values and return a Boolean result:

  • == (Equal to) \(\rightsquigarrow\) Checks if two values are equal.

  • != (Not equal to) \(\rightsquigarrow\) Checks if two values are different.

  • < (Less than) \(\rightsquigarrow\) Checks if one value is smaller than another.

  • > (Greater than) \(\rightsquigarrow\) Checks if one value is larger than another.

  • <= (Less than or equal to) \(\rightsquigarrow\) Checks if one value is smaller than or equal to another.

  • >= (Greater than or equal to) \(\rightsquigarrow\) Checks if one value is larger than or equal to another.

  • Comparison operators return a Boolean result: True if the condition is satisfied, False otherwise (displayed as True and False, not as 1 and 0 as in C++). These operators are commonly used in conditional statements and loops.

  • Comparisons can be chained: 0 < x <= 10 means 0 < x and x <= 10.

Example 7.12: comparison operators

a = 10
b = 5

print("a == b:", a == b)  # Equal to
print("a != b:", a != b)  # Not equal to
print("a < b:", a < b)    # Less than
print("a > b:", a > b)    # Greater than
print("a <= b:", a <= b)  # Less than or equal to
print("a >= b:", a >= b)  # Greater than or equal to
print("0 < b <= a:", 0 < b <= a)  # Chained comparison

Output:

a == b: False
a != b: True
a < b: False
a > b: True
a <= b: False
a >= b: True
0 < b <= a: True

7.4.5 Logical operators

Logical operators, used for logical operations, often in conditional statements:

  • and (Logical AND) \(\rightsquigarrow\) Returns True if both conditions are True.

  • or (Logical OR) \(\rightsquigarrow\) Returns True if at least one condition is True.

  • not (Logical NOT) \(\rightsquigarrow\) Reverses the Boolean value.

  • The logical operators of Python are words, while in C++ they are the symbols &&, || and !.

Example 7.13: logical operators

condition1 = True
condition2 = False

print("condition1:", condition1)
print("condition2:", condition2)

# Logical AND: True only if both conditions are True
print("condition1 and condition2:", condition1 and condition2)

# Logical OR: True if at least one condition is True
print("condition1 or condition2:", condition1 or condition2)

# Logical NOT: reverses the Boolean value
print("not condition1:", not condition1)
print("not condition2:", not condition2)

Output:

condition1: True
condition2: False
condition1 and condition2: False
condition1 or condition2: True
not condition1: False
not condition2: True

7.5 Conditional statements

The comparison and logical operators produce the conditions that decide which instructions are executed.

  • Conditional statements allow executing different blocks of code based on specific conditions.

  • The if statement evaluates a condition. If the condition is True, the indented block is executed.

  • The optional elif (else if) clause checks an additional condition when the previous ones are False.

  • The optional else clause is executed when all preceding conditions are False.

  • No parentheses are needed around the condition, and no curly braces are used: the line of the condition ends with “:” and the block is delimited by indentation.

Example 7.14: conditional statement

number = 10

# Check if number is positive
if number > 0:
    print("The number is positive.")
else:
    print("The number is non-positive.")

Output:

The number is positive.

Example 7.15: if / elif / else

score = 85

if score >= 90:
    grade = "A"
elif score >= 80:
    grade = "B"
elif score >= 70:
    grade = "C"
elif score >= 60:
    grade = "D"
else:
    grade = "F"

print(f"Score: {score}, Grade: {grade}")

Output:

Score: 85, Grade: B

The conditions are evaluated from top to bottom, and only the block of the first true condition is executed: score >= 90 is false and score >= 80 is true, so the grade is "B". This is the same result as the nested ternary operators of the chapter «Introduction to C++».

7.5.1 Conditional expression

  • The conditional expression is the Python version of the ternary operator ?: of C++: it provides a compact way to write simple if-else statements.

  • Syntax: value_if_true if condition else value_if_false

  • If the condition is True, the expression evaluates to value_if_true; otherwise, it evaluates to value_if_false.

Example 7.16: conditional expression

number = 10

# Compact conditional expression
result = "positive" if number > 0 else "non-positive"
print(f"The number is {result}")

# Finding the maximum of two numbers
a, b = 15, 20  # Multiple assignment: a = 15 and b = 20
maximum = a if a > b else b
print(f"Maximum: {maximum}")

# Checking even or odd
n = 7
parity = "even" if n % 2 == 0 else "odd"
print(f"{n} is {parity}")

# Absolute value
x = -5
abs_value = x if x >= 0 else -x
print(f"Absolute value of {x} is {abs_value}")

Output:

The number is positive
Maximum: 20
7 is odd
Absolute value of -5 is 5

The Python library also provides the functions max(a, b) and abs(x), which return the same values.

7.6 Loops

Conditional statements choose whether a block of code is executed; loops decide how many times it is executed.

  • Loops are used to execute a block of code repeatedly. In Python, the two loop constructs are the while loop and the for loop.

7.6.1 The while loop

  • The while loop executes a block of code as long as the condition evaluates to True. If the condition is False from the beginning, the block is never executed.

Example 7.17: while loop

i = 1              # Initialization

while i <= 5:      # Condition
    print(f"Number: {i}")
    i += 1         # Increment (there is no ++ operator in Python)

Output:

Number: 1
Number: 2
Number: 3
Number: 4
Number: 5

As in C++, the condition i <= 5 is evaluated six times: five times it is true, and the sixth time (i equal to 6) it is false and the loop terminates.

7.6.2 The for loop

  • The for loop of Python iterates over the elements of an iterable, such as a list, a string, or a range of integers: at each iteration the loop variable takes the next element.

  • The function range(start, stop, step) generates the sequence of integers from start (included) to stop (excluded), with increment step. If only one argument is given, the sequence starts at \(0\); if step is omitted, it is \(1\); with a negative step the sequence decreases.

  • The pseudo-code loop “for \(i := 1\) to \(n\)” corresponds to for i in range(1, n + 1), and the loop over the indices of a list of size \(n\) is for i in range(n), with \(i = 0, 1, \dots, n-1\).

Example 7.18: for loop with range

for i in range(1, 6):   # i takes the values 1, 2, 3, 4, 5
    print(f"Number: {i}")

The output is the same as in the while loop of Example 7.17. The function list() shows the integers generated by a range:

print(list(range(5)))
print(list(range(1, 6)))
print(list(range(0, 10, 3)))
print(list(range(5, 0, -1)))

Output:

[0, 1, 2, 3, 4]
[1, 2, 3, 4, 5]
[0, 3, 6, 9]
[5, 4, 3, 2, 1]

Example 7.19: for loop over a list

a = [3, 7, 2, 9, 5]

for element in a:
    print(element)

Output:

3
7
2
9
5

The loop visits the elements directly, without using their indices.

7.6.3 The break and continue statements

  • The break statement immediately terminates the loop.

  • The continue statement skips the rest of the current iteration and moves to the next one.

Example 7.20: break and continue

for i in range(1, 11):
    if i % 2 == 0:
        continue  # Skip the even numbers
    if i > 7:
        break     # Stop the loop at the first odd number greater than 7
    print(i, end=" ")
print()

Output:

1 3 5 7

As in the C++ version, the even values of i are skipped by continue; when i is equal to 9 the break statement terminates the loop, and the value 10 is never reached. The final print() writes only the new line.

7.7 Lists

Loops become really useful when they visit collections of values. In Python a collection of values is stored in a list.

  • A list is an ordered, mutable collection of elements, that can hold values of any type. Lists are the main sequence data structure in Python and play the role of the arrays of C++.

  • Lists are enclosed in square brackets [] and elements are separated by commas. Elements are accessed by their index, starting from 0: the elements of a list a of size \(n\) are a[0], a[1], …, a[n-1]. The function len(a) returns the size of the list, and the negative index a[-1] denotes the last element.

  • Unlike the arrays of C++, lists are dynamic: they can grow or shrink at runtime without manual memory management. The instruction a.append(x) adds the element x at the end of the list.

  • The expression [0] * n creates a list of \(n\) zeros. More generally, a list comprehension [expression for i in range(n)] creates the list of the \(n\) values of the expression for \(i = 0, 1, \dots, n-1\); when the loop variable is not used, it is conventionally called _.

Lists are created with [] and indexed starting from 0. No memory allocation or deallocation is required.

Example 7.21: creating and accessing a list

n = 5

# Create a list of n zeros
a = [0] * n

# Assign values
for i in range(n):
    a[i] = i * 2

print(a)       # The whole list
print(a[0])    # First element
print(a[4])    # Last element, index n-1
print(len(a))  # Number of elements

Output:

[0, 2, 4, 6, 8]
0
8
5

Example 7.22: list literal, modification and growth

b = [9, 12, 3, 16]   # List of 4 integers

b[2] = 5             # Assign a new value to the third element
b.append(20)         # The list grows: now it has 5 elements
print(b, len(b))
print(b[-1])         # The last element

squares = [i * i for i in range(6)]  # List comprehension
print(squares)

Output:

[9, 12, 5, 16, 20] 5
20
[0, 1, 4, 9, 16, 25]

Accessing an index that does not exist, for example b[5], stops the program with the error IndexError: list index out of range (in C++ the same access is not checked).

Example 7.23: list literal and iteration over the indices

a = [9, 12, 3, 16, 19, 11, 12]
n = len(a)

for i in range(n):
    print(f"a[{i}] = {a[i]}")

Output:

a[0] = 9
a[1] = 12
a[2] = 3
a[3] = 16
a[4] = 19
a[5] = 11
a[6] = 12

7.7.1 Two-dimensional lists

  • Two-dimensional data can be represented as a list of lists. Each row is itself a list, and elements are accessed with two indices matrix[i][j], both starting from \(0\): for example, if c = [[3, 1, 4], [1, 5, 9]], then c[1][2] is the element in the second row and third column, equal to \(9\).

  • A matrix of \(m\) rows and \(n\) columns filled with zeros is created with the list comprehension [[0] * n for _ in range(m)], which builds \(m\) distinct rows.

Example 7.24: two-dimensional list (matrix)

m = 3   # Number of rows
n = 2   # Number of columns

# Create a matrix of zeros
matrix = [[0] * n for _ in range(m)]

# Assign values
for i in range(m):
    for j in range(n):
        matrix[i][j] = i * j

# Print the matrix
for i in range(m):
    for j in range(n):
        print(f"matrix[{i}][{j}] = {matrix[i][j]}")
print(matrix)

Output:

matrix[0][0] = 0
matrix[0][1] = 0
matrix[1][0] = 0
matrix[1][1] = 1
matrix[2][0] = 0
matrix[2][1] = 2
[[0, 0], [0, 1], [0, 2]]
  • The shorter expression [[0] * n] * m is wrong: it repeats \(m\) times the same row, so a change to one row appears in all the rows.

Example 7.25: a common mistake with two-dimensional lists

wrong = [[0] * 2] * 3                  # Three references to the same row
wrong[0][0] = 1
print(wrong)

right = [[0] * 2 for _ in range(3)]    # Three distinct rows
right[0][0] = 1
print(right)

Output:

[[1, 0], [1, 0], [1, 0]]
[[1, 0], [0, 0], [0, 0]]

7.8 Functions

As in pseudo-code, an algorithm is written as a function that receives the input and returns the output.

  • Functions allow programmers to write modular and reusable code by grouping instructions into a single unit. A function is defined with the keyword def, followed by the function name and the parameter list in parentheses, ending with the symbol “:”.

  • A function in Python consists of:

    1. the keyword def followed by the function name;

    2. a parameter list (optional): specifies the input values, without their data types;

    3. an indented body: the block of code executed when the function is called;

    4. a return statement (optional): returns a value to the caller. A function without return returns the special value None.

  • A function must be defined before the instruction that calls it is executed: for this reason the functions are written at the beginning of the file.

  • The main instructions of a Python program are typically placed at the top level of the file, or inside a block guarded by if __name__ == "__main__":, which ensures that the code runs only when the file is executed directly (and not when it is imported as a module by another file). This block plays the role of the main function of C++.

  • Python source code can also be executed online, for example at the following address:
    www.mycompiler.io/online-python-compiler

Example 7.26: functions

# Function definition
def addition(a, b):
    return a + b  # Returns the sum

# Function definition
def multiplication(a, b):
    return a * b  # Returns the product

if __name__ == "__main__":
    total = addition(5, 10)          # Function call
    print(f"Sum: {total}")

    product = multiplication(5, 10)  # Function call
    print(f"Prod: {product}")

Output:

Sum: 15
Prod: 50

Example 7.27: function operating on a two-dimensional list

def sum_matrix(matrix, rows, columns):
    """Return the sum of all elements of a 2D list."""
    total = 0
    for i in range(rows):
        for j in range(columns):
            total += matrix[i][j]
    return total

if __name__ == "__main__":
    m, n = 3, 2

    # Build the matrix with a nested list comprehension
    matrix = [[i * j for j in range(n)] for i in range(m)]

    result = sum_matrix(matrix, m, n)
    print(f"Sum of matrix elements: {result}")

Output:

Sum of matrix elements: 3

The matrix is [[0, 0], [0, 1], [0, 2]], as in Example 7.24, and the sum of its elements is \(0+0+0+1+0+2 = 3\).

7.8.1 Parameters and return values

In C++ the parameters are passed by value or by reference. In Python every parameter receives the same object as the argument of the caller, and the effect of a function on the caller depends on what the function does with it.

  • If the function assigns a new value to a parameter (for example x = x + 1), only the local name changes: the variable of the caller is not affected. For numbers, the behaviour is the same as the parameters passed by value in C++.

  • If the function modifies the elements of a list received as a parameter (for example a[i] = 0), the change is visible to the caller, as for the arrays passed to a function in C++.

  • A function can return several values at once, separated by commas: they are returned as a tuple, and the caller assigns them to several variables with a multiple assignment. In C++ the same result requires parameters passed by reference.

Example 7.28: parameters and multiple return values

def increment(x):
    x = x + 1           # Changes only the local name x

def fill_with_zeros(a):
    for i in range(len(a)):
        a[i] = 0        # Modifies the list of the caller

def divide(n, m):
    return n // m, n % m  # Returns two values (a tuple)

if __name__ == "__main__":
    k = 5
    increment(k)
    print("After increment:", k)

    b = [4, 7, 1]
    fill_with_zeros(b)
    print("List:", b)

    q, r = divide(17, 5)
    print("Quotient and remainder:", q, r)
    print("Tuple:", divide(17, 5))

Output:

After increment: 5
List: [0, 0, 0]
Quotient and remainder: 3 2
Tuple: (3, 2)

7.9 A complete algorithm: the maximum value in an array

We now put all the pieces together: a function, a loop, a conditional statement and a list.

We consider the problem of finding the maximum value in an array \(a\) of \(n \ge 1\) integer numbers.

  • This is the pseudo-code of the algorithm FindMaximum of the chapter «Pseudo-code»: the entries are indexed from \(1\) to \(n\).

Algorithm: FindMaximum

Input: An array \(a[1..n]\) of \(n \ge 1\) integer numbers
Output: The maximum value in the array \(a\)
1function FindMaximum(a, n)
2\(max := a[1]\)
3for \(i := 2\) to \(n\) do
4if \(a[i] > max\) then
5\(max \leftarrow a[i]\)
6end
7end
8return \(max\)
9end

  • This is the Python implementation. The elements are indexed from \(0\) to \(n-1\), so the initialization uses a[0] and the loop for i in range(1, len(a)) visits the indices \(1, \dots, n-1\). The size \(n\) is not passed as a parameter, because the function obtains it with len(a). The variable is called max_val and not max, so as not to hide the built-in function max(). The function assumes \(n \ge 1\), as the pseudo-code does: for an empty list the access to a[0] stops the program with an IndexError.

    def array_max_value(a):
        """Return the maximum value in the list a (len(a) >= 1)."""
        max_val = a[0]  # Initialize with the first element
    
        for i in range(1, len(a)):
            if a[i] > max_val:
                max_val = a[i]  # Update the maximum
    
        return max_val
    
    if __name__ == "__main__":
        a = [9, 12, 3, 16, 19, 11, 12]
    
        max_val = array_max_value(a)
        print(f"Maximum value: {max_val}")
    

    Output:

    Maximum value: 19
    
  • The test instance can also be generated at random with the module random of the Python library: random.randint(1, 100) returns a random integer between \(1\) and \(100\) (both included). The instruction random.seed(2026) fixes the starting point of the random generator, so that every execution produces the same list; without it, every execution produces a different list.

Example 7.29: a random instance

import random

def array_max_value(a):
    max_val = a[0]
    for i in range(1, len(a)):
        if a[i] > max_val:
            max_val = a[i]
    return max_val

if __name__ == "__main__":
    random.seed(2026)  # Same random list at every execution
    n = 10             # Size of the list
    a = [random.randint(1, 100) for _ in range(n)]

    print(a)
    print(f"Maximum value: {array_max_value(a)}")

Output:

[16, 41, 65, 66, 83, 14, 29, 77, 80, 72]
Maximum value: 83

Example 7.30: step-by-step execution

In each table, the column \(i\) is the index of the Python loop and the column \(i+1\) is the corresponding index of the pseudo-code. The first row is the initialization max_val = a[0].

Instance 1: \(a = [9, 12, 3, 16, 19, 11, 12]\), \(n=7\)

\(i\) (Python) \(i+1\) (pseudo-code) a[i] a[i] > max_val? max_val
– – – – \(9\)
\(1\) \(2\) \(12\) Yes \(12\)
\(2\) \(3\) \(3\) No \(12\)
\(3\) \(4\) \(16\) Yes \(16\)
\(4\) \(5\) \(19\) Yes \(19\)
\(5\) \(6\) \(11\) No \(19\)
\(6\) \(7\) \(12\) No \(19\)

Return: max_val \(= 19\)

Instance 2: \(a = [3, 7, 2, 9, 1]\), \(n=5\)

\(i\) (Python) \(i+1\) (pseudo-code) a[i] a[i] > max_val? max_val
– – – – \(3\)
\(1\) \(2\) \(7\) Yes \(7\)
\(2\) \(3\) \(2\) No \(7\)
\(3\) \(4\) \(9\) Yes \(9\)
\(4\) \(5\) \(1\) No \(9\)

Return: max_val \(= 9\)

7.10 Bitwise operators

The bitwise operators of the chapter «Introduction to C++» exist in Python with the same symbols and the same meaning: & (AND), | (OR), (XOR), ~ (NOT), < < (left shift) and > > (right shift). The function bin() returns the binary representation of an integer, preceded by the prefix 0b.

  • Since the integers of Python have no fixed number of bits, the bitwise NOT does not depend on a data type: ~x is always equal to \(-x-1\). To obtain the \(8\)-bit result of C++, the result is combined with the mask 0xFF (the number \(255\), whose binary representation is \(11111111\)).

Example 7.31: bitwise operators

a = 12  # Binary: 1100
b = 10  # Binary: 1010

print(a & b, a | b, a ^ b)          # AND, OR, XOR
print(bin(a), bin(b), bin(a & b))   # Binary representations
print(5 << 2, 20 >> 2, 20 >> 3)     # Shifts
print(~a, ~a & 0xFF)                # NOT, and its 8-bit version

n = 15
print("odd" if n & 1 else "even")   # Least significant bit

Output:

8 14 6
0b1100 0b1010 0b1000
20 5 2
-13 243
odd

All the values coincide with those of the corresponding examples of the chapter «Introduction to C++».

7.11 Python and C++ side by side

The following table summarizes the main differences between the two languages met in this chapter.

C++ Python
Execution compiled (g++), then executed interpreted (python3)
Data types declared: int x = 5; not declared: x = 5
End of instruction ; end of the line
Blocks curly braces {} : and indentation
Comments // and /\* \*/ # (and """ """)
Boolean values true, false (printed 1, 0) True, False
10 / 3 3 (integer division) 3.3333333333333335
Integer division / between two int //
Power function pow operator \*\*
Increment x++, ++x x += 1
Logical operators &&, ||, ! and, or, not
Ternary operator c ? x : y x if c else y
for loop for (int i = 0; i < n; i++) for i in range(n):
Collections arrays, fixed or dynamic size lists, dynamic
Size of a collection stored in a separate variable len(a)
Several results parameters by reference return of a tuple
Entry point function main top level of the file

Key points of the chapter

  • A Python program is executed by the interpreter (python3) from the first line to the last one; the instructions do not end with “;” and the blocks are delimited by “:” and by the indentation.

  • Variables are created by assignment, without declaring their data type; the integers have no maximum value.

  • The operator / always gives a float; the integer division is // and it rounds down, also for negative numbers.

  • Conditional statements (if, elif, else, and the conditional expression) choose which instructions are executed; loops (while, and for over a range or a list) repeat them.

  • The lists of Python are indexed from \(0\) to \(n-1\), with \(n\) = len(a), while the arrays of the pseudo-code are indexed from \(1\) to \(n\); lists grow with append and need no memory management.

  • A function modifies the list of the caller when it changes its elements, but not a number it receives; several results are returned together as a tuple.


Exercises on this chapter: Introduction to Python