1  Introduction

Python is an object-oriented, easy-to-use, high-level, general-purpose programming language. There is a popular saying in the programming community along the lines of:

Python is the second best language for everything.

which is a testament on how versatile the language really is. Let’s take a look at some of the basics of the language before diving in deeper.

1.1 Basic Data Types

Numbers, strings and booleans are some of the most basic data types found in Python. Let’s quickly go through some basic operations that can be performed on these data types.

1.1.1 Working with numbers

Numbers can be categorized into integers and floats, depending on the use of a decimal point. Both can be used for performing basic arithmetics as shown below:

1 + 1
2
1.0 + 2.5
3.5

This as such is not super useful. However, we can assign numbers (as well as other data types) into variables, which will help us store and manipulate data:

my_iq = 259

print(my_iq)
259

When we input large numbers, we can use underscores to make them more readable:

number_of_people_reading_this_book = 1_000_000

number_of_people_reading_this_book
1000000

Basic arithmetic operations can be performed on numbers using the following syntax:

a = 10
b = 3

# addition
a + b
13
# subtraction
a - b
7
# multiplication
a * b
30
# division
a / b
3.3333333333333335
# floor division
a // b
3
# modulo
a % b
1
# exponentiation
a ** b
1000
Caution

When working with floating point numbers, we might encounter some precision issues stemming from the way computers store numbers. For example, you would expect the following code to return 0.0, but it doesn’t due to the aforementioned limitations:

1 - 0.7 - 0.3
5.551115123125783e-17

This is usually not a problem, but it’s good to keep in mind nevertheless.

1.1.2 Strings

Strings are used to represent text data. They can be enclosed in either single ' or double " quotes. Some basic operations on strings include concatenation and repetition:

"Hello" + " " + "World"
'Hello World'
"Hello" * 3
'HelloHelloHello'

Strings can also be indexed and sliced:

my_string = "Hello World"

# indexing
print(my_string[0])
H
# slicing
print(my_string[0:5])
Hello

Sometimes we might have to convert numbers to strings and vice versa. This can be done using the str() and int() functions:

# converting a number to a string
str(123)
'123'
string_disguised_as_number = '123'

# converting a string to a number
int(string_disguised_as_number)
123

In case of floats, we can use the float() function:

# converting a string to a float
float('3.14')
3.14

If you need to create a string which spans multiple lines, you can use triple quotes to do so:

multiline_string ="""
This is a string
that spans multiple
lines
"""
print(multiline_string)

This is a string
that spans multiple
lines

The three quotation marks are basically just a shorthand for creating a string with newline characters in it, as we can see if we print out the string variable:

multiline_string
'\nThis is a string\nthat spans multiple\nlines\n'

Sometimes it is useful to format strings in a certain way. This can be done using the format() method:

name = "John"
age = 25
formatted_string = "My name is {} and I am {} years old".format(name, age)

print(formatted_string)
My name is John and I am 25 years old

Python 3.6 introduced a new way of formatting strings. F-strings, short for formatted strings, make it easy to add varibles into a string. Let’s show how they work with a simple example:

print(f"My name is {name} and I am {age} years old")
print(f"Next year I will be {age + 1} years old")
My name is John and I am 25 years old
Next year I will be 26 years old

As we can see f-strings are a more concise way of formatting strings, and they come in handy in many situations. For example, as we saw above, calculations with numeric variables can be performed directly inside the f-string, and the result will be automatically formatted as a string.

1.1.3 Booleans

Booleans are used to represent truth values, namely True and False. They can be used in conjunction with logical operators such as and, or and not:

True and False
False

Booleans are most commonly used in conditional statements, which we will cover in a later section.

1.2 Other data types

Python has a number of built-in data structures that can be used to store collections of data. Some of the most commonly used ones are lists, tuples, sets and dictionaries.

1.2.1 Lists

Lists are used to store collections of items. They are ordered, mutable and can contain items of different types. Lists are defined using square brackets []:

my_list = [1, 'two', True, False, 5]

print(my_list)
[1, 'two', True, False, 5]

You can access elements in a list using their index. Just remember that Python uses zero-based indexing:

# get second element
my_list[1]
'two'

You can also slice lists, i.e. get a subset of the list using the following syntax:

# get first three elements
my_list[:3]
[1, 'two', True]

Negative indices can be used to access elements from the end of the list:

# get the last element
my_list[-1]
5

A list can also contain nested lists:

nested_list = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

print(nested_list)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]

Accessing the elements of a nested list is done by chaining the index operators:

nested_list[1][2]
6

This can be tricky at times. Consider yourself warned.

Adding new elements to a list can be done using the append() method:

my_list.append('New element')

print(my_list)
[1, 'two', True, False, 5, 'New element']

We can return the last element from a list using the pop() method:

my_list.pop()
'New element'

This will also remove it from the list as we can see by inspecting the list again:

print(my_list)
[1, 'two', True, False, 5]

If we want to remove a specific element from our list, we can do so by using the remove() method:

my_list.remove('two')

print(my_list)
[1, True, False, 5]

1.2.2 Tuples

Tuples are kind of like lists, but they are immutable, which is a fancy way of saying that once they are created, their size and contents cannot be changed. Tuples are defined using parentheses ():

# creating a tuple
my_tuple = (1, 'two', True, False, 5)

my_tuple
(1, 'two', True, False, 5)

You can access elements in a tuple using their index, just like with lists:

# get second element
my_tuple[1]
'two'

Why would you then create a tuple instead of a list? Well, tuples are faster than lists, and I guess sometimes you want to make sure that the data you are working with doesn’t change to name a few reasons.

1.2.3 Sets

Sets are kind of like lists or tuples, but they are unordered and do not allow duplicate elements. Sets are defined using curly braces {}:

my_set = {1, 2, 3}

my_set
{1, 2, 3}

There is also a set() function can be used to create a set, but we won’t go into that here. Sets are mutable, so you can add and remove elements from them. They are also useful for performing set operations such as union, intersection, difference and symmetric difference:

set1 = {1, 2, 3}
set2 = {3, 4, 5}

# union
set1 | set2
{1, 2, 3, 4, 5}
# intersection
set1 & set2
{3}
# difference

set1 - set2
{1, 2}
# symmetric difference
set1 ^ set2
{1, 2, 4, 5}

1.2.4 Dictionaries

Last but not least we have dictionaries, which are used to store key-value pairs. Dictionaries are unordered, mutable and can contain items of different types. Dictionaries are defined using curly braces {}:

my_dict = {'name': 'Tero', 'likes': 'Pizza', 'is_student': False, 'age': 25}

You can access the value of a key in a dictionary using the key itself:

my_dict['name']
'Tero'

1.3 Summary

That’s it. We have covered the basics of Python data types. Now that this is behind us, we are ready to move on to more advanced and interesting topics. In the upcoming chapter, we will cover control flow statements in Python.