Python Fundamentals I: variables, lists and dictionaries

Preliminary settings in Google Colab

  1. In Settings > AI Assistance, select Hide generative AI features.

  2. In the File menu, select Save a copy in Drive to get a copy of this Notebook in your personal drive, where you will be able to store your edits.

Python as a simple calculator

The very first and simple task that you can try with Python is using it as a simple calculator.

The standard symbols + and - can be used, together with * for multiplication and / for division. To rise one number to the power, you should use **. For example:

[1]:
10 + 3 - 2 + 3*4 + 9/3 + 2**3
[1]:
34.0

Moreover, only round parenthesis can be used in mathematical operations, but can be nested many times:

[2]:
4*(24+1) - 3*(2-5*(3.3-3))
[2]:
98.5

Python as a scientific programmable calculator

Also, Python can be used as a scientific programmable calculator. Consider for example the mathematical expression \(3x^2+2x+5\). You can easily compute its result for diverse values of the variable \(x\)

[3]:
x = 3
3*x**2 + 2*x + 5
[3]:
38

If you want, you can try to change the value of the variable x and run the cell above to see how the result changes.

Python build-in objects

In the previous code cell we used the symbol =. The meaning of the symbol = is different from mathematics, because in Python it means assignment. In practice, the quantity at the right of the = symbol is “stored” into a variable with a name defined on the left of the =. Variables can contain diverse type of “build-in objects”, for example integer numbers, floating point numbers, strings, etc.

Numbers

Integer variables can be created like

[4]:
x=6

You can check the type of the created variable by using the function type

[5]:
type(x)
[5]:
int

type is a function that returns the type of the provided input argument. When you write a statement like x=6, Python understands that some memory should be reserved to store an integer number (int).

In other programming languages, like for example C, C++, FORTRAN and others, the type must be defined whevener a new variable is istantiated.

A floating point variable can be instantiate like:

[6]:
y = 23.45645

To check the corresponding type, you can simply do

[7]:
type(y)
[7]:
float

Strings

Other useful build-in python objects are strings

[8]:
z = "Ciao!"
type(z)
[8]:
str

Printing out variables

To print out the value of a variable, you can type the name of the variable inside a cell and then run it. However, in many cases it is useful to print only some significant figures and properly format the output. In this case you can use f-strings

[9]:
print(f"Our number is {y:.3f}")
Our number is 23.456

If you need only two significant figures, you ca write instead

[10]:
print(f"Our number is {y:.2f}")
Our number is 23.46

If you want the results in scientific format, you can replace f by e:

[11]:
print(f"Our number is {y:.3e}")
Our number is 2.346e+01

Lists

Lists are one of the most useful built-in python objects. They are created using square brackets, and they can contain diverse types of variables (they are heterogeneous).

[12]:
test_list = [12, "Hello", 1.33, 2.53]

List are ordered, and to access the first element of one list, one should start from the index 0.

NOTE: the same indexing used by Python, starting from 0, is also used in other languages like C, C++, Java, JavaScript and many others. In other languages, like for example FORTRAN, R and Matlab, the indexing starts from 1 instead. Of course there are pros and cons with one approach of the other. Only keep in mind that indexing in Python always starts from 0.

[13]:
test_list[0]
[13]:
12

The second element of the list can be accessed using index 1, and so on…

[14]:
test_list[1]
[14]:
'Hello'

The last element of a list can be obtained by using the index -1

[15]:
test_list[-1]
[15]:
2.53

To know the lenght of a list, you can use the function len

[16]:
len(test_list)
[16]:
4

Dictionaries

Dictionaries are other very useful built-in objects. They are not ordered as lists, but they allow to access their content using some user defined keywords named keys. For example

[17]:
studentA = {"name": "Marco", "surname": "Rossi", "age": 27}
[18]:
studentA["name"]
[18]:
'Marco'

Their content can be changed

[19]:
studentA["age"] = 23
studentA
[19]:
{'name': 'Marco', 'surname': 'Rossi', 'age': 23}

Repetitive tasks: the for loop

Repetitive tasks can be automated by using the for loops.
For example, you might need to repeat the same operation on all the elements of a list. For example, one would like to print out something like
[20]:
letters = ["A", "B", "C", "D"]

print("Student ", letters[0])
print("Student ", letters[1])
print("Student ", letters[2])
print("Student ", letters[3])
Student  A
Student  B
Student  C
Student  D

In this case the list contains only 4 elements. But think about a list containing thousands of elements! For repetitive tasks, it is always better to use the for loop syntax. In fact, using the for loop syntax, the same repetitive task can be condensed in two lines:

[21]:
for stud in letters:
    print("Student ", stud)
Student  A
Student  B
Student  C
Student  D

This syntax is:

  • easier to write and to maintain

  • less prone to errors

  • easier to read

NOTE: The line containing the for loop ends with :. Moreover, if you hit <Enter> and the end of the line, the code is automatically indented. This is a peculiar feature of Python, that allows to write code that should be more readable, and also written in a similar way by different programmers. Other languages would allow to write for loops with very different styles, and without forcing any indentation.

Another more common way to write repetitive tasks with Python is the following

[22]:
for i in range(5):
    print("Iteration number", i)
Iteration number 0
Iteration number 1
Iteration number 2
Iteration number 3
Iteration number 4

Indentation matters!

As mentioned in the previous note, indentation matters. In fact, inside a for loop all the lines that are indented are repeated inside the loop

[23]:
for stud in letters:
    print("Student ", stud)
    print("Hello!")
Student  A
Hello!
Student  B
Hello!
Student  C
Hello!
Student  D
Hello!

If the line of code is not indented inside the loop, then it is not repeated

[24]:
for stud in letters:
    print("Student ", stud)
print("Hello!")
Student  A
Student  B
Student  C
Student  D
Hello!

Conditional statemens: if and else

It is also useful to perform some task only if some condition is verified. For example

[25]:
conc = 55.1 # Nitrates concentration [mg/l]

if conc > 50:
    print("This water should be treated")
else:
    print("No need to treat this water")
This water should be treated

Try to change the value of the variable conc and run the cell above to see how it changes.

The code cell above was useful to introduce two things: comparison operators, like for example >, and also the use of comments. In python, all the code written after # is ignored and can be used as comment. Comments longer that one line start with """ and end with """.

Importing modules

Among the others, Python has two important features:

  1. It is minimalist

  2. It is general purpose

In fact, it is designed to run also on hardware with very limited memory and CPU requirements, like for example onto satellites, Raspberrt PI and so on.
Also, it can be used for many purposes: creating web pages, doing plots, doing math, AI applications and so on. To avoid overcharging every script, the required functions are only imported on demand, using the syntax import.

For example, by default the function to compute the square root of a number is not available. To use it, you should do

[26]:
import math
math.sqrt(9)
[26]:
3.0

Sometimes, the names of the modules are quite long and repeating them all the time makes the code less readable. In these cases, one can use as to introduce an alias for the imported module

[27]:
import math as m
m.sqrt(9)
[27]:
3.0

Sometimes, one can also explicitly import only one precise function from a module, using the syntax from

[28]:
from math import sqrt
sqrt(9)
[28]:
3.0

WARNING: In this case, the syntax seems to be simpler, as you do not need to recall every time the name of the module. At the same time, in some cases this syntax can create ambiguities: suppose for example that you have a function that has the same name in two different modules. How can you be sure to use the right one?

Getting help

Another nice feature of Python is that it self contains its documentation. Of course, if you have an internet connection or a nice Integrated Development Environment (IDE) you can easily look for a nicely formatted documentation.

Otherwise, you can simply type

[29]:
help(math.sqrt)
Help on built-in function sqrt in module math:

sqrt(x, /)
    Return the square root of x.

to get a brief description and explanation about the function you would like to use. Quite often, also small examples are provided.

[ ]: