Introduction to Python
Disclaimer: This post has been translated to English using a machine translation model. Please, let me know if you find any mistakes.
1. Summary
Let's make a brief introduction to Python, explaining the data types we have, operators, the use of functions and classes. Additionally, we will see how to use iterable objects, how to use modules, etc.
2. Data types in Python
There are 7 data types in Python
- Text type:
str
2. Numerical:int
,float
,complex
3. Sequences:list
,tuple
,range
4. Mapping:dict
5. Sets:set
,frozenset
6. Booleans:bool
7. Binaries:bytes
,bytearray
,memoryview
We can get the data type using the type()
function.
type(5.)
float
Python is a dynamically typed language, which means you can have a variable of one type and then assign it another type.
a = 5type(a)
int
a = 'MaximoFN'type(a)
str
Python types variables for you, but if you want to type them yourself, you can do so.
b = int(5.1)type(b), b
(int, 5)
Although b
has been initialized as 5.1
, that is, it should be of type float
, when we type it as int
, we see that it is of type int
and its value is 5
2.1. Strings
strings
are sequences of characters, these can be defined with double quotes "
or single quotes '
string = "MaximoFN"string
'MaximoFN'
string = 'MaximoFN'string
'MaximoFN'
To write a very long string
and not have a line that takes up too much space, it can be introduced on multiple lines
string = """Este es un ejemplo decomo estoy introduciendo un stringen varias lineas"""string
'Este es un ejemplo de como estoy introduciendo un string en varias lineas'
string = '''Este es un ejemplo decomo estoy introduciendo un stringen varias lineas'''string
'Este es un ejemplo de como estoy introduciendo un string en varias lineas'
However, we see that in the middle it has inserted the character , this character indicates a line break. If we use the
print()
function, we will see that it no longer appears.
print(string)
Este es un ejemplo decomo estoy introduciendo un stringen varias lineas
As we have said, strings are sequences of characters, so we can navigate and iterate through them.
for i in range(10):# Se indica a la función print que cuando imprima no termine con un salto de# linea para escribir todo en la misma lineaprint(string[i], end='')
Este es un
We can get the length of our string using the len()
function.
len(string)
73
Check if there is a specific string within ours
'ejemplo' in string
True
Strings have certain useful attributes, such as converting everything to uppercase.
print(string.upper())
ESTE ES UN EJEMPLO DECOMO ESTOY INTRODUCIENDO UN STRINGEN VARIAS LINEAS
all in lowercase
print(string.lower())
este es un ejemplo decomo estoy introduciendo un stringen varias lineas
Replace characters
print(string.replace('o', '@'))
Este es un ejempl@ dec@m@ est@y intr@duciend@ un stringen varias lineas
Get all the words
print(string.split())
['Este', 'es', 'un', 'ejemplo', 'de', 'como', 'estoy', 'introduciendo', 'un', 'string', 'en', 'varias', 'lineas']
You can see all the string methods in this link
Another useful thing that can be done with strings is concatenating them.
string1 = 'Maximo'string2 = 'FN'string1 + string2
'MaximoFN'
We previously explained that the character \n
corresponds to a line break. This special character is part of a series of special characters called Escape Characters
. Let's look at some others.
If we declare a string with double quotes and want to add a double quote inside the string, we use the escape character \"
print("Este es el blog de \"MaximoFN\"")
Este es el blog de "MaximoFN"
The same with the single quote, we add \'
print('Este es el blog de \'MaximoFN\'')
Este es el blog de 'MaximoFN'
Now we have the problem of whether we want to add the \ character since, as we have seen, it is an escape character
, so we solve it by putting a double backslash \.
print('Este es el blog de \\MaximoFN\\')
Este es el blog de \MaximoFN\
We have already seen the newline escape character \n
print('Este es el blog de \nMaximoFN')
Este es el blog deMaximoFN
If we want to write from the beginning of the line, we add \r
print('Esto no se imprimirá \rEste es el blog de MaximoFN')
Este es el blog de MaximoFN
If we want to add a large space (indent) we use \t
print('Este es el blog de \tMaximoFN')
Este es el blog de MaximoFN
We can delete a character with \b
print('Este es el blog de \bMaximoFN')
Este es el blog deMaximoFN
We can add the ASCII code in octal using \ooo
print('\115\141\170\151\155\157\106\116')
MaximoFN
Or add the ASCII code in hexadecimal using \xhh
print('\x4d\x61\x78\x69\x6d\x6f\x46\x4e')
MaximoFN
Lastly, we can convert another type of data into a string
n = 5print(type (n))string = str(n)print(type(string))
<class 'int'><class 'str'>
2.2. Numbers
2.2.1. Integers
Integer numbers
n = 5n, type(n)
(5, int)
2.2.2. Float
Floating-point numbers
n = 5.1n, type(n)
(5.1, float)
2.2.3. Complex
Complex numbers
n = 3 + 5jn, type(n)
((3+5j), complex)
2.2.4. Conversion
Numbers can be converted between types
n = 5n = float(n)n, type(n)
(5.0, float)
n = 5.1n = complex(n)n, type(n)
((5.1+0j), complex)
n = 5.1n = int(n)n, type(n)
(5, int)
A complex number cannot be converted to type int
or type float
2.3. Sequences
2.3.1. Lists
Lists store multiple items in a variable. They are declared using the []
symbols, with items separated by commas.
lista = ['item0', 'item1', 'item2', 'item3', 'item4', 'item5']lista
['item0', 'item1', 'item2', 'item3', 'item4', 'item5']
We can get the length of a list using the len()
function.
len(lista)
6
Lists can have items of different types
lista = ['item0', 1, True, 5.3, "item4", 5, 6.6]lista
['item0', 1, True, 5.3, 'item4', 5, 6.6]
In Python, counting starts from position 0, that is, if we want to get the first element of the list
lista[0]
'item0'
But one of the powerful things about Python is that if we want to access the last position we can use negative indices
lista[-1]
6.6
If instead of the last position in the list we want the penultimate one
lista[-2]
5
If we only want a range of values, for example, from the second to the fifth item, we access them via [2:5]
lista[2:5]
[True, 5.3, 'item4']
If the first number in the range is omitted, it means we want from the first item in the list to the indicated item, that is, if we want from the first item to the fifth, we use [:5]
lista[:5]
['item0', 1, True, 5.3, 'item4']
If the last number in the range is omitted, it means we want from the indicated item to the last. That is, if we want from the third item to the last, we use [3:]
.
lista[3:]
[5.3, 'item4', 5, 6.6]
We can also choose the range of items with negative numbers, that is, if we want from the third-to-last to the second-to-last we use [-3:-1]
. This is useful when you have lists whose length is unknown, but you know you want a range of values from the end, for example, because the list was created with measurements that are being taken and you want to know the last averages.
lista[-3:-1]
['item4', 5]
It can be checked if an item is in the list
'item4' in lista
True
2.3.1.1. Editing lists
Lists in Python are dynamic, meaning they can be modified. For example, you can modify the third item.
lista[2] = Falselista
['item0', 1, False, 5.3, 'item4', 5, 6.6]
A range of values can also be modified.
lista[1:4] = [1.1, True, 3]lista
['item0', 1.1, True, 3, 'item4', 5, 6.6]
Values can be added to the end of the list using the append()
method.
lista.append('item7')lista
['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item7']
Or we can insert a value at a specific position using the insert()
method.
lista.insert(2, 'insert')lista
['item0', 1.1, 'insert', True, 3, 'item4', 5, 6.6, 'item7']
Lists can be joined using the extend()
method.
lista2 = ['item8', 'item9']lista.extend(lista2)lista
['item0', 1.1, 'insert', True, 3, 'item4', 5, 6.6, 'item7', 'item8', 'item9']
It is not necessary to extend the list using another list; it can be done using another iterable data type in Python (tuples
, sets
, dictionaries
, etc).
tupla = ('item10', 'item11')lista.extend(tupla)lista
['item0',1.1,'insert',True,3,'item4',5,6.6,'item7','item8','item9','item10','item11']
We can remove a specific position using the pop()
method.
lista.pop(2)lista
['item0',1.1,True,3,'item4',5,6.6,'item7','item8','item9','item10','item11']
If the index is not specified, the last item is removed.
lista.pop()lista
['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item7', 'item8', 'item9', 'item10']
Or an item can be removed knowing its value using the remove()
method.
lista.remove('item7')lista
['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item8', 'item9', 'item10']
With the del()
function, you can also delete an item from the specified position.
del lista[3]lista
['item0', 1.1, True, 'item4', 5, 6.6, 'item8', 'item9', 'item10']
If the index is not specified, the entire list is deleted.
With the clear()
method, I empty the list.
lista.clear()lista
[]
The number of items with a specific value can be obtained using the count()
method.
lista = [5, 4, 6, 5, 7, 8, 5, 3, 1, 5]lista.count(5)
4
You can also get the first index of an item with a specific value using the index()
method.
lista = [5, 4, 6, 5, 7, 8, 5, 3, 1, 5]lista.index(5)
0
2.3.1.2. List comprehension
We can operate through the list
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]newlist = []# Iteramos por todos los items de la listafor x in fruits:# Si el item contiene el caracter "a" lo añadimos a newlistif "a" in x:newlist.append(x)newlist
['apple', 'banana', 'mango']
Some of the powerful features of Python are list comprehensions
, which allow you to do everything in one line and make the code more compact.
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]newlist = [x for x in fruits if "a" in x]newlist
['apple', 'banana', 'mango']
The syntax is as follows:
newlist = [expression for item in iterable if condition == True]```
It can be used to perform operations on the original list
newlist = [x.upper() for x in fruits if "a" in x]newlist
['APPLE', 'BANANA', 'MANGO']
2.3.1.3. Sorting lists
To order lists we use the sort()
method.
lista = [5, 8, 3, 4, 9, 5, 6]lista.sort()lista
[3, 4, 5, 5, 6, 8, 9]
It also sorts them alphabetically
lista = ["orange", "mango", "kiwi", "pineapple", "banana"]lista.sort()lista
['banana', 'kiwi', 'mango', 'orange', 'pineapple']
When sorting alphabetically, distinguish between uppercase and lowercase.
lista = ["orange", "mango", "kiwi", "Pineapple", "banana"]lista.sort()lista
['Pineapple', 'banana', 'kiwi', 'mango', 'orange']
They can be sorted in descending order using the attribute reverse = True
lista = [5, 8, 3, 4, 9, 5, 6]lista.sort(reverse = True)lista
[9, 8, 6, 5, 5, 4, 3]
They can be ordered in the way we want using the key
attribute.
def myfunc(n):# devuelve el valor absoluto de n - 50return abs(n - 50)lista = [100, 50, 65, 82, 23]lista.sort(key = myfunc)lista
[50, 65, 23, 82, 100]
This can be used, for example, so that when sorting, it does not distinguish between uppercase and lowercase.
lista = ["orange", "mango", "kiwi", "Pineapple", "banana"]lista.sort(key = str.lower)lista
['banana', 'kiwi', 'mango', 'orange', 'Pineapple']
The list can be reversed using the reverse
method.
lista = [5, 8, 3, 4, 9, 5, 6]lista.reverse()lista
[6, 5, 9, 4, 3, 8, 5]
2.3.1.4. Copying lists
Lists cannot be copied using list1 = list2
, because if list1
is modified, list2
is also modified.
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = lista1lista1[0] = Truelista2
[True, 8, 3, 4, 9, 5, 6]
So, you have to use the copy()
method.
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = lista1.copy()lista1[0] = Truelista2
[5, 8, 3, 4, 9, 5, 6]
Or you have to use the list constructor list()
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = list(lista1)lista1[0] = Truelista2
[5, 8, 3, 4, 9, 5, 6]
2.3.1.5. Concatenating lists
Lists can be concatenated using the +
operator.
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = ['a', 'b', 'c']lista = lista1 + lista2lista
[5, 8, 3, 4, 9, 5, 6, 'a', 'b', 'c']
Or using the extend
method
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = ['a', 'b', 'c']lista1.extend(lista2)lista1
[5, 8, 3, 4, 9, 5, 6, 'a', 'b', 'c']
Another way to concatenate is to repeat the tuple X times using the *
operator
lista1 = ['a', 'b', 'c']lista2 = lista1 * 3lista2
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
2.3.2 Tuples
Tuples are similar to lists, they store multiple items in a variable, can contain items of different types, but they cannot be modified or reordered. They are defined using ()
, with items separated by commas.
Since they cannot be modified, tuples execute a bit faster than lists, so if you don't need to modify the data, it's better to use tuples instead of lists.
tupla = ('item0', 1, True, 3.3, 'item4', True)tupla
('item0', 1, True, 3.3, 'item4', True)
Its length can be obtained using the len()
function.
len (tupla)
6
To create tuples with a single element, it is necessary to add a comma
tupla = ('item0',)tupla, type(tupla)
(('item0',), tuple)
To access an element of the tuple, proceed in the same way as with lists.
tupla = ('item0', 1, True, 3.3, 'item4', True)print(tupla[0])print(tupla[-1])print(tupla[2:4])print(tupla[-4:-2])
item0True(True, 3.3)(True, 3.3)
We can check if there is an item in the tuple
'item4' in tupla
True
2.3.2.1. Modifying tuples
Although tuples are not mutable, they can be modified by converting them to lists, modifying the list, and then converting it back to a tuple.
lista = list(tupla)lista[4] = 'ITEM4'tupla = tuple(lista)tupla
('item0', 1, True, 3.3, 'ITEM4', True)
By converting it to a list, we can make all the modifications seen in lists.
What can be done is to delete the complete tuple
del tuplaif 'tupla' not in locals():print("tupla eliminada")
tupla eliminada
2.3.22. Unpack tuples
When we create tuples, we are actually packaging data
tupla = ('item0', 1, True, 3.3, 'item4', True)tupla
('item0', 1, True, 3.3, 'item4', True)
but we can unpack them
item0, item1, item2, item3, item4, item5 = tuplaitem0, item1, item2, item3, item4, item5
('item0', 1, True, 3.3, 'item4', True)
If we want to extract fewer elements than the length of the tuple, we add a *
item0, item1, item2, *item3 = tuplaitem0, item1, item2, item3
('item0', 1, True, [3.3, 'item4', True])
The asterisk *
can be placed elsewhere if, for example, what we want is the last item.
item0, item1, *item2, item5 = tuplaitem0, item1, item2, item5
('item0', 1, [True, 3.3, 'item4'], True)
2.3.23. Concatenating tuples
Tuples can be concatenated using the +
operator
tupla1 = ("a", "b" , "c")tupla2 = (1, 2, 3)tupla3 = tupla1 + tupla2tupla3
('a', 'b', 'c', 1, 2, 3)
Another way to concatenate is to repeat the tuple X times using the *
operator
tupla1 = ("a", "b" , "c")tupla2 = tupla1 * 3tupla2
('a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c')
2.3.24. Tuple Methods
Tuples have two methods, the first is the count()
method which returns the number of times an item appears within the tuple.
tupla = (5, 4, 6, 5, 7, 8, 5, 3, 1, 5)tupla.count(5)
4
Another method is index()
which returns the first position of an item within the tuple.
tupla = (5, 4, 6, 5, 7, 8, 5, 3, 1, 5)tupla.index(5)
0
2.3.3. Range
With range()
we can create a sequence of numbers, starting from 0 (by default), it increments by 1 (by default) and stops before a specified number.
range(start, stop, step)```
For example, if we want a sequence from 0 to 5 (not including 5)
for i in range(5):print(f'{i} ', end='')
0 1 2 3 4
If for example we don't want it to start at 0
for i in range(2, 5):print(f'{i} ', end='')
2 3 4
for i in range(-2, 5):print(f'{i} ', end='')
-2 -1 0 1 2 3 4
Lastly, if we don't want it to increment by 1, for example, if we want a sequence of even numbers.
for i in range(0, 10, 2):print(f'{i} ', end='')
0 2 4 6 8
2.4. Dictionaries
Dictionaries are used to store data in key:value
pairs. They are mutable, unordered, and do not allow duplicates. They are defined using the {}
symbols. They support items of different data types.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964,"colors": ["red", "white", "blue"]}diccionario
{'brand': 'Ford','model': 'Mustang','year': 1964,'colors': ['red', 'white', 'blue']}
As has been said, duplicates are not allowed.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964,"year": 2000,"colors": ["red", "white", "blue"]}diccionario["year"]
2000
Its length can be obtained using the len()
function.
len(diccionario)
4
As can be seen, the length is 4 and not 5, since year
is counted only once.
2.4.1. Accessing Items
To access an element, we can do so through its key
diccionario["model"]
'Mustang'
It can also be accessed using the get
method.
diccionario.get("model")
'Mustang'
To know all the key
s of dictionaries, you can use the keys()
method.
diccionario.keys()
dict_keys(['brand', 'model', 'year', 'colors'])
A variable can be used to point to the key
s of the dictionary, so that calling it once is necessary
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se declara una vez la variable que apunta a las keysx = diccionario.keys()print(x)# Se añade una nueva keydiccionario["color"] = "white"# Se consulta la variable que apunta a las keyprint(x)
dict_keys(['brand', 'model', 'year'])dict_keys(['brand', 'model', 'year', 'color'])
To get the values from the dictionary, you can use the values()
method.
diccionario.values()
dict_values(['Ford', 'Mustang', 1964, 'white'])
A variable can be used to point to the values
of the dictionary, so that calling it once is necessary.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se declara una vez la variable que apunta a los valuesx = diccionario.values()print(x)# Se modifica un valuediccionario["year"] = 2020# Se consulta la variable que apunta a los valuesprint(x)
dict_values(['Ford', 'Mustang', 1964])dict_values(['Ford', 'Mustang', 2020])
If what you want are the entire item
s, that is, key
s and value
s, you should use the items()
method.
diccionario.items()
dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 2020)])
A variable can be used to point to the item
s in the dictionary, so that calling it once is necessary.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se declara una vez la variable que apunta a los itemsx = diccionario.items()print(x)# Se modifica un valuediccionario["year"] = 2020# Se consulta la variable que apunta a los itemsprint(x)
dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 1964)])dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 2020)])
It can be checked if a key
exists in the dictionary
"model" in diccionario
True
2.4.2. Modify the items
An item
can be modified by accessing it directly.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario["year"] = 2020diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}
Or it can be modified using the update()
method.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario.update({"year": 2020})diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}
2.4.3. Adding Items
An item
can be added in this way:
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario["colour"] = "blue"diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 1964, 'colour': 'blue'}
Or it can be added using the update()
method.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario.update({"colour": "blue"})diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 1964, 'colour': 'blue'}
2.4.4. Remove items
An item
with a specific key
can be removed using the pop()
method.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina un itemdiccionario.pop("model")diccionario
{'brand': 'Ford', 'year': 1964}
Or you can delete an item
with a specific key
using del
by specifying the key
name between the []
symbols.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina un itemdel diccionario["model"]diccionario
{'brand': 'Ford', 'year': 1964}
The dictionary will raise an error if del
is used and the key
of an item
is not specified.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina un itemdel diccionarioif 'diccionario' not in locals():print("diccionario eliminado")
diccionario eliminado
If what is desired is to remove the last item
introduced, the popitem()
method can be used.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina el último item introducidodiccionario.popitem()diccionario
{'brand': 'Ford', 'model': 'Mustang'}
If you want to clear the dictionary, you can use the clear()
method.
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}diccionario.clear()diccionario
{}
2.4.5. Copying dictionaries
Dictionaries cannot be copied using dictionary1 = dictionary2
, because if you modify dictionary1
, dictionary2
will also be modified.
diccionario1 = {"brand": "Ford","model": "Mustang","year": 1964}diccionario2 = diccionario1diccionario1["year"] = 2000diccionario2["year"]
2000
So, you have to use the copy()
method.
diccionario1 = {"brand": "Ford","model": "Mustang","year": 1964}diccionario2 = diccionario1.copy()diccionario1["year"] = 2000diccionario2["year"]
1964
Or you have to use the dictionary constructor dict()
diccionario1 = {"brand": "Ford","model": "Mustang","year": 1964}diccionario2 = dict(diccionario1)diccionario1["year"] = 2000diccionario2["year"]
1964
2.4.6. Anidated Dictionaries
Dictionaries can have items
of any data type, even other dictionaries. These types of dictionaries are called nested
dictionaries.
diccionario_nested = {"child1" : {"name" : "Emil","year" : 2004},"child2" : {"name" : "Tobias","year" : 2007},"child3" : {"name" : "Linus","year" : 2011}}diccionario_nested
{'child1': {'name': 'Emil', 'year': 2004},'child2': {'name': 'Tobias', 'year': 2007},'child3': {'name': 'Linus', 'year': 2011}}
child1 = {"name" : "Emil","year" : 2004}child2 = {"name" : "Tobias","year" : 2007}child3 = {"name" : "Linus","year" : 2011}diccionario_nested = {"child1" : child1,"child2" : child2,"child3" : child3}diccionario_nested
{'child1': {'name': 'Emil', 'year': 2004},'child2': {'name': 'Tobias', 'year': 2007},'child3': {'name': 'Linus', 'year': 2011}}
2.4.7. Dictionary Methods
These are the methods that can be used on dictionaries.
2.4.8. Dictionary comprehension
igual que podemos hacer list comprehensions
mediante la sintaxis
list comprehension = [expression for item in iterable if condition == True]```
We can create `dictionary comprehensions` using the following syntax
``` python
dictionary comprehension = {key_expression: value_expression for item in iterable if condition == True}```
Let's start with an example
dictionary_comprehension = {x: x**2 for x in (2, 4, 6) if x > 2}dictionary_comprehension
{4: 16, 6: 36}
2.5. Sets
2.5.1. Set
Sets
are used in Python to store a collection of items in a single variable. They can store items of different types. They are unordered and do not have an index.
They differ from lists in that they have neither order nor index.
They are declared using the symbols
Since set
is a reserved word in Python, we create a set
with the name set_
set_ = {'item0', 1, 5.3, "item4", 5, 6.6}set_
{1, 5, 5.3, 6.6, 'item0', 'item4'}
Items cannot be duplicated, if a duplicate item is found, only one is kept.
set_ = {'item0', 1, 5.3, "item4", 5, 6.6, 'item0'}set_
{1, 5, 5.3, 6.6, 'item0', 'item4'}
The length of the set
can be obtained using the len()
function.
len(set_)
6
As can be seen, the length of the set is 6 and not 7, since it remains with only one 'item0'
It can be checked if an item is in the set
'item4' in set_
True
2.5.1.1. Add items
An element can be added to a set using the add()
method.
set_.add(8.8)set_
{1, 5, 5.3, 6.6, 8.8, 'item0', 'item4'}
Another set can be added using the update()
method.
set2 = {"item5", "item6", 7}set_.update(set2)set_
{1, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6'}
Items can also be added from iterable data types in Python.
lista = ["item9", 10, 11.2]set_.update(lista)set_
{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6', 'item9'}
2.5.1.2. Remove items
An item can be removed using the remove()
method.
set_.remove('item9')set_
{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6'}
Or using the discard()
method
set_.discard('item6')set_
{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5'}
The pop()
method can remove the last item, but since set
s are unordered, there's no way to know which is the last item. The pop()
method returns the removed item.
print(f"set antes de pop(): {set_}")eliminado = set_.pop()print(f"Se ha eliminado {eliminado}")
set antes de pop(): {1, 5, 5.3, 6.6, 8.8, 7, 10, 11.2, 'item5', 'item0', 'item4'}Se ha eliminado 1
The clear()
method can be used to empty the set.
set_.clear()set_
set()
Lastly, with del
you can delete the set
del set_if 'set_' not in locals():print("set eliminado")
set eliminado
2.5.1.3. Unir ítems
a way to unite sets is through the union()
method
set1 = {"a", "b" , "c"}set2 = {1, 2, 3}set3 = set1.union(set2)set3
{1, 2, 3, 'a', 'b', 'c'}
Another way is through the update()
method, but this way adds a set to another, it doesn't create a new one.
set1 = {"a", "b" , "c"}set2 = {1, 2, 3}set1.update(set2)set1
{1, 2, 3, 'a', 'b', 'c'}
These methods of union remove the duplicates, but if we want to get the duplicated elements in two sets we can use the intersection()
method.
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set3 = set1.intersection(set2)set3
{'apple'}
If we want to get the duplicate elements in two sets, but without creating a new set, we can use the intersection_update()
method.
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set1.intersection_update(set2)set1
{'apple'}
Now, if we want to get rid of the duplicates, we can use the symmetric_difference()
method.
The difference between this and the union of two sets is that in the union, all items are included, but duplicates are only taken once. Now we keep only those that are not duplicated.
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set3 = set1.symmetric_difference(set2)set3
{'banana', 'cherry', 'google', 'microsoft'}
If we want to remove the duplicates without creating a new set, we use the symmetric_difference_update()
method.
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set1.symmetric_difference_update(set2)set1
{'banana', 'cherry', 'google', 'microsoft'}
2.5.1.4. Methods of sets
These are the methods that can be used with sets.
2.5.2. FrozenSet
The frozenset
s are like set
s but with the safety that they are immutable, just as tuple
s are like list
s but immutable. Therefore, we cannot add or remove items.
2.6. Booleans
There are only two booleans in Python: True
and False
The function bool()
can evaluate if anything is True
or False
.
print(bool("Hello"))print(bool(15))print(bool(0))
TrueTrueFalse
2.6.1. Other Data Types True and False
The following data are True
:* Any string that is not empty* Any number except 0* Any list, tuple, dictionary, or set that is not empty
print(bool("Hola"))print(bool(""))
TrueFalse
print(bool(3))print(bool(0))
TrueFalse
lista = [1, 2, 3]print(bool(lista))lista = []print(bool(lista))
TrueFalse
tupla = (1, 2, 3)print(bool(tupla))tupla = ()print(bool(tupla))
TrueFalse
diccionario = {"brand": "Ford","model": "Mustang","year": 1964,"colors": ["red", "white", "blue"]}print(bool(diccionario))diccionario.clear()print(bool(diccionario))
TrueFalse
set_ = {'item0', 1, 5.3, "item4", 5, 6.6}print(bool(set_))set_.clear()print(bool(set_))
TrueFalse
2.7. Binaries
2.7.1. Bytes
The bytes
type is an immutable sequence of bytes. It only accepts ASCII characters. Bytes can also be represented using integers whose values must satisfy 0 <= x < 256
.
To create a byte type, we must introduce the character b
byte = b"MaximoFN"byte
b'MaximoFN'
It can also be created using its constructor bytes()
byte = bytes(10)byte
b' '
byte = bytes(range(10))byte
b' '
Bytes can be concatenated using the +
operator.
byte1 = b'DeepMax'byte2 = b'FN'byte3 = byte1 + byte2byte3
b'DeepMaxFN'
Repetition with the *
operator
byte1 = b'MaximoFN 'byte2 = byte1 * 3byte2
b'MaximoFN MaximoFN MaximoFN '
We can check if a character is within the string
b'D' in byte1
False
These are the methods that can be used with bytes
.
2.7.2. Bytearray
The bytearray
s are the same as bytes
except that they are mutable.
byte_array = bytearray(b'MaximoFN')byte_array
bytearray(b'MaximoFN')
2.7.3. MemoryView
The memoryview
objects allow Python code to access the internal data of an object that supports the buffer protocol without making copies.
The memoryview()
function allows direct read and write access to the byte-oriented data of an object without the need to copy it first. This can result in significant performance gains when working with large objects, as it does not create a copy when slicing.
buffer protocol, it can create another access object to modify large data without copying it. This makes the program use less memory and increase execution speed.
byte_array = bytearray('XYZ', 'utf-8')print(f'Antes de acceder a la memoria: {byte_array}')mem_view = memoryview(byte_array)mem_view[2]= 74print(f'Después de acceder a la memoria: {byte_array}')
Antes de acceder a la memoria: bytearray(b'XYZ')Después de acceder a la memoria: bytearray(b'XYJ')
3. Operators
3.1. Arithmetic Operators
Operator sum +
3 + 5
8
Operator minus -
3 - 5
-2
Multiplication operator *
3 * 5
15
Division operator /
3 / 5
0.6
Modulo operator %
. Returns the remainder of a division.
25 % 2
1
Exponent operator **
5 ** 2
25
Integer division operator //
25 // 2
12
3.2. Comparison Operators
Operator is equal ==
1 == 1
True
Operator is different !=
1 != 2
True
Operator is greater than >
3 > 2
True
Operator is less than <
2 < 3
True
Operator is greater than or equal to >=
3 >= 3
True
Operator is less than or equal to <=
3 <= 3
True
3.3. Logical Operators
Operator and
True and True
True
Operator or
True or False
True
Operator not
not False
True
3.4. Identity Operators
Operator is
5.3 is 5.3
True
Operator is not
5.3 is not 5
True
3.5. Membership Operators
Operator in
x = ["apple", "banana"]"banana" in x
True
Operator not in
x = ["apple", "banana"]"orange" not in x
True
3.6. Bitwise Operators
Operator AND &
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101c = a & b; # 12 = 0000 1100c
12
Operator OR |
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101c = a | b; # 61 = 0011 1101c
61
XOR operator ^
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101c = a ^ b; # 49 = 0011 0001c
49
Operator NOT ~
a = 60 # 60 = 0011 1100c = ~a; # -61 = 1100 0011c
-61
Left shift operator <<
a = 60 # 60 = 0011 1100c = a << 2; # 240 = 1111 0000c
240
Right shift operator >>
a = 60 # 60 = 0011 1100c = a >> 2; # 15 = 0000 1111c
15
3.7. Assignment Operators
Operator `=
a = 5a
5
Operator +=
. x += y
is equivalent to x = x + y
a += 5a
10
Operator -=
. x -= y
is equivalentTox = x - y
a -= 5a
5
Operator *=
. x *= y
is equivalent to x = x * y
a *= 3a
15
Operator /=
. x /= y
is equivalentTox = x / y
a /= 3a
5.0
Operator %=
. x %= y
is equivalentTox = x % y
a = 25a %= 2a
1
Operator //=
. x //= y
is equivalent to x = x // y
a = 25a //= 2a
12
Operator **=
. x **=y
is equivalent to x = x ** y
a = 5a **= 2a
25
Operator &=
. x &= y
is equivalent to x = x & y
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101a &= b; # 12 = 0000 1100a
12
Operator |=
. x |= y
is equivalent to x = x | y
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101a |= b; # 61 = 0011 1101a
61
Operator ^=
. x ^= y
is equivalent to x = x ^ y
.
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101a ^= b; # 49 = 0011 0001a
49
Operator >>=
. x >>= y
is equivalent to x = x >> y
.
a = 60 # 60 = 0011 1100a <<= 2; # 240 = 1111 0000a
240
Operator <<=
. x <<= y
is equivalent to x = x << y
a = 60 # 60 = 0011 1100a >>= 2; # 15 = 0000 1111a
15
4. Flow Control
To be able to use the flow control tools, it is necessary to add a colon :
and on a new line write the code with indentation.
Unlike other languages, Python requires indentation (white space at the beginning of a line) to define the code inside a control structure.
4.1. If
With if
we can create conditionals
if len('MaximoFN') == 8:print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
If we want to createMoreThanOneConditionWeCanUseelif
if len('MaximoFN') < 8:print('MaximoFN tiene menos de 8 caracteres')elif len('MaximoFN') == 8:print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
If what we want is to execute something in case ofNoConditionsMatch, we can use else
if len('MaximoFN') < 8:print('MaximoFN tiene menos de 8 caracteres')elif len('MaximoFN') > 8:print('MaximoFN tiene más de 8 caracteres')else:print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
If we want to write everything in oneLine
if len('MaximoFN') == 8: print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
Equal, if we want to write everything in one line, ButWithSeveral conditions
print('MaximoFN tiene menos de 8 caracteres') if len('MaximoFN') < 8 else print('MaximoFN tiene más de 8 caracteres') if len('MaximoFN') > 8 else print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
If, for example, we want to create the structure of the if
without specifying the conditions at the moment, we can use pass
if len('MaximoFN') < 8:print('MaximoFN tiene menos de 8 caracteres')elif len('MaximoFN') > 8:passelse:print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
4.2. While
The while
loop executes as long as the condition is True
i = 0string = 'MaximoFN'while len(string) > i:print(string[i], end='')i += 1
MaximoFN
If we want the loop to stop under some condition, we use break
i = 0string = 'MaximoFN'while len(string) > i:if string[i] == 'F':breakprint(string[i], end='')i += 1
Maximo
If we want one of the iterations not to executeForSomeReason, we use continue
i = 0string = 'Maximo FN'while len(string) > i:if string[i] == ' ':i += 1continueprint(string[i], end='')i += 1
MaximoFN
The else
block can be executed if the condition of the while
loop is not True
i = 0string = 'MaximoFN'while len(string) > i:print(string[i], end='')i += 1else:print("\nSe ha terminado el while")
MaximoFNSe ha terminado el while
4.3. For
The for
loop is used to execute code while iterating over an iterable. This iterable can be any Python iterable (string
, list
, tuple
, range
, dictionary
, set
).
string = 'MaximoFN'for x in string:print(x, end='')
MaximoFN
lista = ['M', 'a', 'x', 'i', 'm', 'o', 'F', 'N']for x in lista:print(x, end='')
MaximoFN
tupla = ('M', 'a', 'x', 'i', 'm', 'o', 'F', 'N')for x in tupla:print(x, end='')
MaximoFN
string = 'MaximoFN'for i in range(len(string)):print(string[i], end='')
MaximoFN
diccionario = {"letra1": "M","letra2": "a","letra3": "x","letra4": "i","letra5": "m","letra6": "o","letra7": "F","letra8": "N",}for x in diccionario.values():print(x, end='')
MaximoFN
Sets can also be iterated, but since they are unordered, there is no control over the order of execution.
set_ = {'M', 'a', 'x', 'i', 'm', 'o', 'F', 'N'}for x in set_:print(x, end='')
NximoaMF
If we want the loop to stop under some condition, we use break
string = 'MaximoFN'for x in string:if x == 'F':breakprint(x, end='')
Maximo
If we want one of the iterations not to executeForSomeReason, we use continue
string = 'Maximo FN'for x in string:if x == ' ':continueprint(x, end='')
MaximoFN
The else
block can be executed if the condition of the while
loop is not True
string = 'MaximoFN'for x in string:print(x, end='')else:print("\nSe ha terminado el for")
MaximoFNSe ha terminado el for
If forExample we want to create the structure of the for
loop, at this point, to be able to fill it in later, we can use pass
string = 'MaximoFN'for x in string:passprint('Interior del for no codificado')
Interior del for no codificado
5. Functions
A function is a portion of code that can be executed multiple times as needed. It can take arguments and can return data as a result.
To define a function, you start with the reserved word def
, followed by the functionName, parentheses ()
, a colon :
, and then continue on a new indented line with the function code.
def funcion():print('MaximoFN')
To call the function, it is only necessary to write its name.
funcion()
MaximoFN
Functions canTakeAnyArgumentsPassedAsParametersAndSeparatedByCommas
def funcion(string1, string2):print(string1 + ' ' + string2)funcion("Hola", "MaximoFN")
Hola MaximoFN
When calling the function, you must pass it the same number of arguments that were declared; otherwise, you would get an error.
If we don't know the arguments that the functionWillReceive *args
, it means that a *
is used before the arguments to indicate that the number ofArguments is variable.
When doing this, you passIt a tuple
(which is immutable)WithTheArguments
def funcion(*argumentos):numero_argumentos = len(argumentos)for i in range(numero_argumentos):print(argumentos[i], end=' ')funcion("funcion", "con", "varios", "argumentos", "sin", "especificar", "cuantos")
funcion con varios argumentos sin especificar cuantos
In case you don't know the order of the arguments of a function, you can specify the argument you want to pass by indicating its name.
def funcion(argumento1, argumento2, argumento3):print(argumento1 + ' '+ argumento2 + ' ' + argumento3)funcion(argumento3 = "MaximoFN", argumento1 = "Blog", argumento2 = "de")
Blog de MaximoFN
In case you want to pass the arguments with their names, butEnCaseOf does notKnow howManyArguments there are to pass, you canUse **kwargs
. In this case, a dictionary with the arguments will be passed.
def funcion(**kargumentos):print("Autor del blog: " + kargumentos["autor"])funcion(blog = "Blog", pertenencia = "de", autor = "MaximoFN")
Autor del blog: MaximoFN
If we want some argument to have a default value between the parameters of the function. This way, if the default value is not passed to the function, the argument in the function will have the default value.
def funcion(argumento1, argumento2, argumento3 = "MaximoFN"):print(argumento1 + ' '+ argumento2 + ' ' + argumento3)funcion("Blog", "de")
Blog de MaximoFN
Any type of data can be passed as an argument. For example, if a list
is passed as an argument, within the function, that argument will be treated as a list
.
Se puede pasar cualquier tipo de dato como argumento. Por ejemplo, si se pasa una `lista` como argumento, dentro de la función, dicho argumento será tratado como una `lista`.
Becomes:
Any type of data can be passed as an argument. For example, if a `list` is passed as an argument, within the function, that argument will be treated as a `list`.
def funcion(argumento):longitud_lista = len(argumento)for i in range(longitud_lista):print(argumento[i], end=' ')funcion(["Blog", "de", "MaximoFN"])
Blog de MaximoFN
Functions can return data, this is done using the reserved word return
.
Las funciones pueden devolver datos, esto se hace mediante la palabra reservada `return`
Functions can return data, this is done using the reserved word `return`.
def funcion(argumento):longitud_lista = len(argumento)string = ""for i in range(longitud_lista):string = string + argumento[i] + ' 'return stringprint(funcion(["Blog", "de", "MaximoFN"]))
Blog de MaximoFN
Can return more than one data
def funcion(argumento):longitud_lista = len(argumento)string0 = argumento[0]string1 = argumento[1]string2 = argumento[2]return string0, string1, string2dato0, dato1, dato2 = funcion(["Blog", "de", "MaximoFN"])print(dato0 + ' ' + dato1 + ' ' + dato2)
Blog de MaximoFN
If one of the returned data is not of interest, we can skip it using _
.
a, _, c = some_function()
This is a common practice in Python to ignore certain values that are returned but not needed.
If one of the returned data is not of interest, we can skip it using _
.
a, _, c = some_function()
def funcion(argumento):longitud_lista = len(argumento)string0 = argumento[0]string1 = argumento[1]string2 = argumento[2]return string0, string1, string2_, _, dato_de_interes = funcion(["Blog", "de", "MaximoFN"])print(dato_de_interes)
MaximoFN
If, for example, we want to create the structure of the function but do not want to, for the moment, code the interior, we can use pass
.
def my_function():
pass
Si queremos indicar que la función aún no está completa, podemos usar un comentario o TODO
:
def my_function():
# TODO: Implementar la lógica de la función
pass
def funcion():passfuncion()
A function can call itself, this is called recursion or function recursivity.
A function can call itself, this is called recursion or function recursivity.
Este método es útil para resolver problemas que se pueden descomponer en subproblemas más pequeños y similares al problema original.
This method is useful for solving problems that can be broken down into smaller, similar subproblems.
Si necesitas más ejemplos o tienes dudas, no dudes en pregar.
If you need more examples or have doubts, don't hesitate to ask.
For example, we can use this property to calculate the factorial of a number.
def factorial(n):if n == 0 or n == 1:return 1else:return n * factorial(n-1)factorial(5)
120
5.1. Built-in functions
There is a series of predefined functions in Python that can be used, such as the abs()
function, which returns the absolute value.
There is a series of predefined functions in Python that can be used, such as the `abs()` function, which returns the absolute value.
abs(-5)
5
The following is a list of these functions
import builtinsdir(builtins)
['ArithmeticError','AssertionError','AttributeError','BaseException','BlockingIOError','BrokenPipeError','BufferError','BytesWarning','ChildProcessError','ConnectionAbortedError','ConnectionError','ConnectionRefusedError','ConnectionResetError','DeprecationWarning','EOFError','Ellipsis','EnvironmentError','Exception','False','FileExistsError','FileNotFoundError','FloatingPointError','FutureWarning','GeneratorExit','IOError','ImportError','ImportWarning','IndentationError','IndexError','InterruptedError','IsADirectoryError','KeyError','KeyboardInterrupt','LookupError','MemoryError','ModuleNotFoundError','NameError','None','NotADirectoryError','NotImplemented','NotImplementedError','OSError','OverflowError','PendingDeprecationWarning','PermissionError','ProcessLookupError','RecursionError','ReferenceError','ResourceWarning','RuntimeError','RuntimeWarning','StopAsyncIteration','StopIteration','SyntaxError','SyntaxWarning','SystemError','SystemExit','TabError','TimeoutError','True','TypeError','UnboundLocalError','UnicodeDecodeError','UnicodeEncodeError','UnicodeError','UnicodeTranslateError','UnicodeWarning','UserWarning','ValueError','Warning','ZeroDivisionError','__IPYTHON__','__build_class__','__debug__','__doc__','__import__','__loader__','__name__','__package__','__spec__','abs','all','any','ascii','bin','bool','breakpoint','bytearray','bytes','callable','chr','classmethod','compile','complex','copyright','credits','delattr','dict','dir','display','divmod','enumerate','eval','exec','filter','float','format','frozenset','get_ipython','getattr','globals','hasattr','hash','help','hex','id','input','int','isinstance','issubclass','iter','len','license','list','locals','map','max','memoryview','min','next','object','oct','open','ord','pow','print','property','range','repr','reversed','round','set','setattr','slice','sorted','staticmethod','str','sum','super','tuple','type','vars','zip']
5.2. Function Documentation
We can add an explanation of a function we create by including a comment at the beginning of the function, so when we call the built-in function
help()
, it will display that explanation.
def funcion():"Esta es la explicación de la función"Nonehelp(funcion)
Help on function funcion in module __main__:funcion()Esta es la explicación de la función
Another option to see the function explanation is to use the function's __doc__
doc` is a built-in attribute that contains the docstring of the function. You can access it like this:
print(my_function.__doc__)
- Pros:
- It's a direct and easy way to access the docstring.
- Cons:
- It is less readable and less commonly used than the
help()
function.
- It is less readable and less commonly used than the
def my_function():
"""
This is a sample function to demonstrate the use of `__doc__`.
"""
pass
print(my_function.__doc__)
This will output the docstring of my_function
.
"""
This is a sample function to demonstrate the use of `__doc__`.
"""
funcion.__doc__
'Esta es la explicación de la función'
5.3. Decorators
Decorators are a Python feature that allows adding new features to a function.
# Example of a decorator
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
Note: This is a basic example of how decorators work in Python. They can be used to modify or enhance the behavior of functions or methods without permanently modifying the original code.
If you want to learn more about decorators, you can check the official Python documentation or other resources online. A decorator function is created that takes another function as a parameter. Then the decorator function adds the new feature to the function it receives.
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
Este es un ejemplo de cómo se ve un decorador básico en Python. La función my_decorator
toma func
como parámetro y crea una función wrapper
que agrega funcionalidades antes y después de llamar a func
.
Cuando se llama a say_hello()
, en realidad se está llamando a wrapper()
def decorador(parametro_funcion):"""Agrega barritas arriba y abajo de la funcion"""def envoltorio():"""Aplica las barritas al texto"""print("==================")parametro_funcion()print("==================")return envoltoriodef funcion():print("MaximoFN")funcion_envoltorio = decorador(funcion)print('Función sin decoradores: ')funcion()print('\nFunción con decoradores: ')funcion_envoltorio()
Función sin decoradores:MaximoFNFunción con decoradores:==================MaximoFN==================
But another more powerful way to use decorators is by using @
and the decorator's name before the function.
@decorator
def function():
pass
Este es un ejemplo de cómo se ve en el código.
@decorator
def example_function():
print("Esta función está decorada.")
Este método es más limpio y legible, especialmente cuando se usan múltiples decoradores.
@decorator1
@decorator2
def another_example_function():
print("Esta función tiene dos decoradores.")
Esto facilita la lectura y el mantenimiento del código, ya que los decoradores se aplican de abajo hacia arriba.
@decorator1
@decorator2
def yet_another_example_function():
print("Esta función tiene dos decoradores en orden inverso.")
Es importante notar que el orden en el que se aplican los decoradores puede afectar el comportamiento de la función decorada. That is, first the decorator is defined and then a function is called with the defined decorator.
def my_decorator(func):
def wrapper():
print("Something is happening before the function is called.")
func()
print("Something is happening after the function is called.")
return wrapper
@my_decorator
def say_hello():
print("Hello!")
say_hello()
- This will output:
Something is happening before the function is called.
Hello!
Something is happening after the function is called.
Es decir, primero se define el decorador y a continuación se llama a una función con el decorador definido.
def decorador2(parametro_funcion2):"""Agrega barritas arriba y abajo de la funcion"""def envoltorio2():"""Aplica las barritas al texto"""print("==================")parametro_funcion2()print("==================")return envoltorio2@decorador2def funcion2():print("MaximoFN")print('Función con decoradores: ')funcion2()
Función con decoradores:==================MaximoFN==================
5.4. *args
and **kwargs
*args
and **kwargs
are optional arguments that can be used when defining a function in Python. The syntax is as follows:
def my_function(arg1, arg2, *args, **kwargs): # function code here```
2.5.1. *args
*args
is used to pass a variable number of arguments to a function. By using *args
, you can pass a variable number of arguments to the function without having to specify the exact number of arguments the function needs. The arguments are received in the function as a tuple.
def saludo(saludo, *nombres):for nombre in nombres:print(f"{saludo}, {nombre}")saludo("Hola", "Alicia", "Roberto", "Carlos")
Hola, AliciaHola, RobertoHola, Carlos
2.5.2. **kwargs
**kwargs
is used in the same way, but to send a variable number of keyword arguments to a function. When using **kwargs
, you can send a variable number of arguments to the function and specify the value of each argument using its name. The arguments are received in the function as a dictionary.
def saludo(saludo, **personas):for key, value in personas.items():print(f"{saludo} {key}, tu edad es {value} años")saludo("Hola", Juan=22, Maria=32, Pedro=25)
Hola Juan, tu edad es 22 añosHola Maria, tu edad es 32 añosHola Pedro, tu edad es 25 años
6. Additional Functions
6.1. Lambda functions
A lambda function is a small anonymous function.
una función *lambda* es una pequeña función anónima.
A *lambda* function is a small anonymous function.
Este método es útil para funciones cortas y simples que no necesitan un nombre propio. A lambda function can take any number of arguments, but can only have one expression.
A *lambda* function can take any number of arguments, but can only have one expression.
This command is already in English, so no translation is needed. However, if you need the entire text in English, here it is:
A *lambda* function can take any number of arguments, but can only have one expression.
Lambda functions are defined as follows:lambda arguments : expression
x = lambda a : a + 10print(x(5))
15
x = lambda a, b, c : a + b + cprint(x(5, 6, 2))
13
The power of lambda is best demonstrated when you use them as an anonymous function inside another function.
def my_function(n):
return lambda a, b: (a + b) * n
doubler = my_function(2)
print(doubler(1, 2)) # Output: 6
En este ejemplo, my_function
devuelve una función lambda que toma dos argumentos a
y b
, y multiplica su suma por n
.
- Uso en funciones de orden superior:
Las funciones lambda son muy útiles cuando se utilizan con funciones de orden superior como
map()
,filter()
, yreduce()
.
# Uso con map()
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # Output: [1, 4, 9, 16, 25]
# Uso con filter()
even_numbers = list(filter(lambda x: x % 2 == 0, numbers))
print(even_numbers) # Output: [2, 4]
# Uso con reduce()
from functools import reduce
product = reduce(lambda x, y: x * y, numbers)
print(product) # Output: 120
En estos ejemplos, las funciones lambda se utilizan para definir operaciones breves y concisas que se aplican a cada elemento de una lista o para reducir una lista a un solo valor.
def myfunc(n):return lambda a : a * nmydoubler = myfunc(2)mytripler = myfunc(3)print(f"mydoubler: {mydoubler(11)}")print(f"mytripler: {mytripler(11)}")
mydoubler: 22mytripler: 33
6.2. map
Function
The map
function allows applying a function to each element of an iterable structure.
# Example usage of map
numbers = [1, 2, 3, 4]
squared = map(lambda x: x**2, numbers)
print(list(squared)) # Output: [1, 4, 9, 16]
La función map
toma dos argumentos: la función que se aplicará y el iterable sobre el cual se aplicará la función. El resultado es un objeto iterable que puede convertirse en una lista u otra estructura de datos.
# Another example
words = ["hello", "world", "python"]
uppercased = map(str.upper, words)
print(list(uppercased)) # Output: ['HELLO', 'WORLD', 'PYTHON']
Esta función es muy útil para transformar datos de manera concisa y eficiente.
lista = [1, 2, 3]def funcion_mas_1(valor):return valor + 1lista_modificada = list(map(funcion_mas_1, lista))lista_modificada
[2, 3, 4]
This is equivalent to using list comprehension
lista_modificada = [funcion_mas_1(x) for x in lista]lista_modificada
[2, 3, 4]
6.3. filter
Function
The filter
function allows selecting the elements from an iterable structure that meet a condition.
# Example usage of filter
numbers = [1, 2, 3, 4, 5]
even_numbers = filter(lambda x: x % 2 == 0, numbers)
print(list(even_numbers)) # Output: [2, 4]
La función filter
es útil para filtrar elementos en una lista o cualquier otra estructura iterable basada en una condiciónThe filter
function is useful for filtering elements in a list or any other iterable structure based on a condition.
lista = [1, 2, 3, 4, 5, 6, 7]def esPar(valor):return valor % 2 == 0lista_filtrada = list(filter(esPar, lista))lista_filtrada
[2, 4, 6]
This is equivalent to using list comprehension
lista_filtrada = [x for x in lista if esPar(x)]lista_filtrada
[2, 4, 6]
6.4. reduce
Function
The reduce
function allows performing accumulative tasks on iterable structures.
La función `reduce` permite realizar tareas acumulativas sobre estructuras iterables.
Becomes:
The `reduce` function allows performing accumulative tasks on iterable structures.
from functools import reducelista = [1, 22, 33]def acumular(valor, acumulador):print(f'valor = {valor}, acumulador = {acumulador}, acumulacion = {valor + acumulador}')return valor + acumuladoracumulacion = reduce(acumular, lista)print(f'\nacumulacion = {acumulacion}')
valor = 1, acumulador = 22, acumulacion = 23valor = 23, acumulador = 33, acumulacion = 56acumulacion = 56
6.5. zip
Function
With the zip
function, you can combine multiple iterable structures into one, meaning it allows you to group several elements from the structures Ax into a single structure B. The structure B is composed of tuples of the elements from the structures Ax.
nombres = ["Manolo", "Andres", "Fernando"]altura = [181, 178, 180]my_zip = list(zip(nombres, altura))my_zip
[('Manolo', 181), ('Andres', 178), ('Fernando', 180)]
65. Generators
Suppose we want to iterate over a sequence of numbers, but in a special way that no loop provides. This can be solved with generators. To do this, the generator function should not return the value with return
, but with yield
so that it knows it needs to continue iterating.
def iterador_custom(N):for i in range (N):if i % 3 == 0:yield igenerador = iterador_custom(20)for i in generador:print(i)
0369121518
We just created an iterator for numbers that are multiples of 3
666. High order functions
We can create functions that receive other functions as parameters, so the function that receives another function as a parameter is called a higher-order function (high order function). Let's see an example.
def increment(x):return x + 1def hof(f, x):return 2*f(x)print(hof(increment, 3))
8
7. Classes and Objects
Python is an object-oriented programming language. Almost everything in Python is an object, with its attributes and methods.
A class is like an object constructor or a "blueprint" for creating objects.
To create a class, the reserved word class
is used.
class Clase:variable = 'MaximoFN'
Once the class has been created, an object of that class can be created.
objeto = Clase()Clase.variable
'MaximoFN'
Normally, classes have an initialization function that runs when an object of the class is created. This function is called dunder init and is written as __init__()
. The dunder init function must always be passed the variable self
, which refers to the class itself, and then any additional variables you want to pass.
This function is usually used to initialize the variables of the classes, or to execute the code that is needed when an object of the class is created.
class Persona:def __init__(self, nombre, edad):self.nombre = nombreself.edad = edadobjeto_persona = Persona("Miguel", 36)print(objeto_persona.nombre)print(objeto_persona.edad)
Miguel36
In addition to the initial dunder init function, more functions can be created. These functions are called methods of the class. These methods always need to be passed the self
variable.
class Persona:def __init__(self, nombre, edad):self.nombre = nombreself.edad = edaddef saludar(self):print(f'Hola mi nombre es {self.nombre} y tengo {self.edad} años')objeto_persona = Persona("Miguel", 36)objeto_persona.saludar()
Hola mi nombre es Miguel y tengo 36 años
The variable self
does not have to be called self
, it can have any name, but within each class it must always be the same. But by convention, self
is usually used.
class Persona:def __init__(yo_mismo, nombre, edad):yo_mismo.nombre = nombreyo_mismo.edad = edaddef saludar(yo_mismo):print(f'Hola mi nombre es {yo_mismo.nombre} y tengo {yo_mismo.edad} años')objeto_persona = Persona("Miguel", 36)objeto_persona.saludar()
Hola mi nombre es Miguel y tengo 36 años
Variables of objects can be modified.
objeto_persona.nombre = 'Marta'objeto_persona.saludar()
Hola mi nombre es Marta y tengo 36 años
Even removing them
del objeto_persona.nombre
The entire object can also be deleted.
del objeto_persona
If, for example, we want to create the structure of the class but do not want to, for now, code the interior, we can use pass
class Persona:passobjeto_persona = Persona()
7.1. Inheritance
Inheritance allows us to define a class that inherits all the methods and properties from another class. The parent class is the class from which inheritance occurs, also called the base class. The child class is the class that inherits from another class, also called the derived class.
We create a parent class
class Persona:def __init__(self, nombre, apellido):self.nombre = nombreself.apellido = apellidodef imprimir_nombre(self):print(f'Me llamo {self.nombre} {self.apellido}')objeto_padre = Persona("Laura", "Perez")objeto_padre.imprimir_nombre()
Me llamo Laura Perez
To create the child class, you need to indicate between parentheses, when declaring the class, which class it inherits from.
class Estudiante(Persona):pass
And when creating the object of the child class, the parameters that the parent class needs are passed.
objeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()
Me llamo Mariano Sanz
So far, the child class has inherited the functions from the parent class, but we can modify them by overriding them. For example, by overriding the dunder init function.
If the dunder init function is rewritten, if we want to call the dunder init function of the parent class, we need to call it.
There are two ways to do this, one is through the name of the parent class. In this case, you have to pass it the self
variable.
class Estudiante(Persona):def __init__(self, nombre, apellido):Persona.__init__(self, nombre, apellido)objeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()
Me llamo Mariano Sanz
Another way is through super()
, in this case you don't need to pass the self
variable.
class Estudiante(Persona):def __init__(self, nombre, apellido):super().__init__(nombre, apellido)objeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()
Me llamo Mariano Sanz
By modifying the functions, new code can be added.
class Estudiante(Persona):def __init__(self, nombre, apellido, curso):Persona.__init__(self, nombre, apellido)self.curso = cursodef imprimir_nombre(self):Persona.imprimir_nombre(self)print(f'Estoy en el curso número {self.curso}')objeto_hijo = Estudiante("Mariano", "Sanz", 4)objeto_hijo.imprimir_nombre()
Me llamo Mariano SanzEstoy en el curso número 4
Lastly, new methods can be added.
class Estudiante(Persona):def __init__(self, nombre, apellido, curso):Persona.__init__(self, nombre, apellido)self.curso = cursodef imprimir_nombre(self):Persona.imprimir_nombre(self)print(f'Estoy en el curso número {self.curso}')def imprimir_estudiante(self):print(f"Soy un estudiante del curso número {self.curso}")objeto_hijo = Estudiante("Mariano", "Sanz", 4)objeto_hijo.imprimir_nombre()objeto_hijo.imprimir_estudiante()
Me llamo Mariano SanzEstoy en el curso número 4Soy un estudiante del curso número 4
7.2. Operator Overloading
We can define basic operations, such as addition, between multiple objects of a class. For example, if we have a class that represents a vector, we can define addition and multiplication between objects of that class.
class Vector:def __init__(self, x, y):self.x = xself.y = ydef __add__(self, other):return Vector(self.x + other.x, self.y + other.y)def __mul__(self, other):return Vector(self.x * other.x, self.y * other.y)def __str__(self):return f"Vector ({self.x}, {self.y})"v1 = Vector(1, 2)v2 = Vector(3, 4)print(v1 + v2) # Vector (4, 6)print(v1 * v2) # Vector (3, 8)
Vector (4, 6)Vector (3, 8)
All possible operator overloads are:
__add__(self, other)
: overloads the addition operator (+
).*__sub__(self, other)
: overloads the subtraction operator (-
).*__mul__(self, other)
: overloads the multiplication operator (*
).*__truediv__(self, other)
: overloads the division operator (/
).*__floordiv__(self, other)
: overloads the floor division operator (//
). *__mod__(self, other)
: overloads the modulo operator (%
).*__divmod__(self, other)
: overloads thedivmod()
function. *__pow__(self, other)
: overloads the power operator (**
). *__lshift__(self, other)
: overloads the left shift operator (<<
).*__rshift__(self, other)
: overloads the right shift operator (>>
).*__and__(self, other)
: overloads the and operator (&
).*__or__(self, other)
: overloads the or operator (|
).*__xor__(self, other)
: overloads the xor operator (^
). *__lt__(self, other)
: overloads the less than comparison operator (<
).*__le__(self, other)
: overloads the less than or equal to comparison operator (<=
).*__eq__(self, other)
: overloads the equality comparison operator (==
).*__ne__(self, other)
: overloads the not equal to comparison operator (!=
).*__gt__(self, other)
: overloads the greater than comparison operator (>
).*__ge__(self, other)
: overloads the greater than or equal to comparison operator (>=
).*__neg__(self)
: overloads the negation operator (-
).*__pos__(self)
: overloads the unary positive operator (+
). *__abs__(self)
: overloads theabs()
function.*__invert__(self)
: overloads the inversion operator (~
).*__complex__(self)
: overloads thecomplex()
function. *__int__(self)
: overloads theint()
function. *__float__(self)
: overloads thefloat()
function.
7.3. Custom Iterators
As we have seen in section 2 (Python Data Types), there are some data types that can be iterated over. But we can create our own iterable class, as long as it has the functions __len__
and __getitem__
.
class custonIterator:def __init__(self, n):self.items = [i for i in range(n)]def __len__(self):return len(self.items)def __getitem__(self, index):return self.items[index]iterator = custonIterator(10)print(len(iterator)) # 10print(iterator[0]) # 0print(iterator[1]) # 1
1001
Now we can iterate over the object of our class with for
loops, for example
for i in iterator:print(i, end=" ") # 0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
7.4. Calling Objects as Functions
We might want to call an object of a function as if it were a class. This can be achieved by adding the __call__
function to the class.
class potencia:def __init__(self, base):self.base = basedef __call__(self, potencia):return self.base ** potenciapotencia_cuadrado = potencia(2)print(potencia_cuadrado(3)) # 8
8
7.5. Private Attributes and Functions
When we create a class, we can make some attributes or functions private so they cannot be accessed from outside the class. To do this, you need to add __
before the attribute or method.
class Privados:def __init__(self):self.publico = "Soy público"self.__privado = "Soy privado"def getPrivado(self):return self.__privadodef setPrivado(self, valor):self.__privado = valordef __funcion_privada(self):return "Soy una función privada"def funcion_publica(self):return self.__funcion_privada()privados = Privados()print("Acceso al atributo publico: ", end="")try:print(f"{privados.publico}")except:print("\tNo se puede acceder al atributo privado")print("Acceso al atributo privado: ", end="")try:print(f"{privados.__privado}")except:print("\tNo se puede acceder al atributo privado")print("Acceso al atributo privado mediante el accesor: ", end="")try:print(f"{privados.getPrivado()}")except:print("\tNo se puede acceder al atributo privado mediante el accesor")print("Llamada a la función privada: ", end="")try:print(f"{privados.__funcion_privada()}")except:print("\tNo se puede llamar a la función privada")print("Llamada a la función pública: ", end="")try:print(f"{privados.funcion_publica()}")except:print("\tNo se puede llamar a la función pública")
Acceso al atributo publico: Soy públicoAcceso al atributo privado: No se puede acceder al atributo privadoAcceso al atributo privado mediante el accesor: Soy privadoLlamada a la función privada: No se puede llamar a la función privadaLlamada a la función pública: Soy una función privada
8. Iterators
An iterator is an object that contains a countable number of values. An iterator is an object over which you can iterate, meaning you can traverse all the elements. Technically, in Python, an iterator is an object that implements the iterator protocol, which consists of the methods iter() and next().
Lists
, tuples
, dictionaries
, and sets
are all iterable objects. They are iterable containers from which you can get an iterator.
All these objects have an iter()
method that is used to get an iterator:
tupla = ("manzana", "plátano", "cereza")iterable = iter(tupla)print(next(iterable))print(next(iterable))print(next(iterable))
manzanaplátanocereza
string = "plátano"iterable = iter(string)print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')print(next(iterable), end=' ')
p l á t a n o
The for
loop actually creates an iterator object and calls the next()
method on each iteration.
tupla = ("manzana", "plátano", "cereza")for x in tupla:print(x)
manzanaplátanocereza
string = "plátano"for x in string:print(x, end=' ')
p l á t a n o
8.1. Create an iterator object
To create an object/class as an iterator, you need to implement the methods __iter__()
and __next__()
.
class Numeros:def __iter__(self):self.a = 1return selfdef __next__(self):x = self.aself.a += 1return xobjeto_iterador = Numeros()iterador = iter(objeto_iterador)print(next(iterador), end=' ')print(next(iterador), end=' ')print(next(iterador), end=' ')print(next(iterador), end=' ')print(next(iterador), end=' ')
1 2 3 4 5
The previous example would continue indefinitely if it had enough calls to next()
, or if it were used in a for
loop.
To prevent the iteration from continuing forever, we can use the StopIteration
statement.
In the __next__()
method, we can add a termination condition to raise an error if the iteration is performed a specific number of times:
class Numeros:def __iter__(self):self.a = 1return selfdef __next__(self):if self.a <= 20:x = self.aself.a += 1return xelse:raise StopIterationobjeto_iterador = Numeros()iterador = iter(objeto_iterador)for x in iterador:print(x, end=' ')
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
8.2. Iterating getting the index and value
We can iterate over an iterable object, obtaining its index and value in each iteration using the enumerate()
method.
string = "MaximoFN"for index, valor in enumerate(string):print(f"En la posición {index}, está el caracter {valor}")
En la posición 0, está el caracter MEn la posición 1, está el caracter aEn la posición 2, está el caracter xEn la posición 3, está el caracter iEn la posición 4, está el caracter mEn la posición 5, está el caracter oEn la posición 6, está el caracter FEn la posición 7, está el caracter N
8.3. Iterating simultaneously over two iterable objects
If we have two iterable objects of the same length, we can iterate over both at the same time using the zip()
method.
string1 = 'MaximoFN__'string2 = 'PythonPost'if len(string1) == len(string2):for valor1, valor2 in zip(string1, string2):print(f"En el primer string hay {valor1}, en el segundo string hay {valor2}")
En el primer string hay M, en el segundo string hay PEn el primer string hay a, en el segundo string hay yEn el primer string hay x, en el segundo string hay tEn el primer string hay i, en el segundo string hay hEn el primer string hay m, en el segundo string hay oEn el primer string hay o, en el segundo string hay nEn el primer string hay F, en el segundo string hay PEn el primer string hay N, en el segundo string hay oEn el primer string hay _, en el segundo string hay sEn el primer string hay _, en el segundo string hay t
9. Variable Scope
A variable is only available within the region where it is created. This is called scope.
9.1. Local Scope
A variable created within a function belongs to the local scope of that function and can only be used within that function.
def funcion():x = 300print(x)funcion()
300
The variable x
is not available outside the function, but it is available to any function within it.
def funcion():x = 300def funcion_interna():print(x)funcion_interna()funcion()
300
9.2. Global Scope
A variable created in the main body of the Python code is a global variable and belongs to the global scope. Global variables are available from any scope, global and local.
x = 300def funcion():print(f'Ámbito local: {x}')funcion()print(f'Ámbito global: {x}')
Ámbito local: 300Ámbito global: 300
If two variables are created, one global and one local, both with the same name, Python will create them as two distinct variables.
x = 300def funcion():x = 200print(f'Variable local: {x}')funcion()print(f'Variable global: {x}')
Variable local: 200Variable global: 300
If a global variable needs to be created, but it is declared in the local scope, the global
keyword can be used.
The keyword global
makes the variable global.
def funcion():global xx = 300funcion()print(f'Variable global: {x}')
Variable global: 300
In addition, the use of the global
keyword allows making a change to a global variable within a function.
x = 300def funcion():global xx = 200funcion()print(f'Variable global: {x}')
Variable global: 200
10. Modules
A module is a file that contains a set of functions that you want to include in your application.
To create a module, simply save the code you want in a file with the file extension .py
Tip: In Jupyter notebooks (Colab is an online Jupyter notebook) if we write the character
!
before a command we can execute terminal commands
First, let's see which directory we are in. For that, we use the pwd
command (print working directory).
!pwd
/home/wallabot/Documentos/web/portafolio/posts
Let's create a folder to create our modules with the mkdir
(make directory) command.
!mkdir introduccion_python
Let's see what files are in our folder. We will do this using the ls
(list) command.
!ls introduccion_python
We see that it is empty, so we create a new .py
file in which we are going to create our module.
%%writefile introduccion_python/modulo1.pydef funcion_del_modulo(nombre):print("Hola, " + nombre)
Writing introduccion_python/modulo1.py
We check again what files are in our folder
!ls introduccion_python
modulo1.py __pycache__
We see that a file modulo1.py
has been created. We can now use it.
To use an external module, you have to use the import
keyword. To use the functions of the module, you have to put first the name of the module, a .
and then the name of the function you want to use.
import introduccion_python.modulo1introduccion_python.modulo1.funcion_del_modulo('MaximoFN')
Hola, MaximoFN
If we want our module to have a specific name within our code, we can use the word as
import introduccion_python.modulo1 as mod1mod1.funcion_del_modulo('MaximoFN')
Hola, MaximoFN
If the module has several functions, but we only want to import one, we can do this using the from
and import
keywords. The form would be
from <module> import <function>```
In this case, there is no need to specify the module name when calling the function.
%%writefile introduccion_python/modulo2.pydef funcion1_del_modulo(nombre):print("Hola, " + nombre + ", funcion 1")def funcion2_del_modulo(nombre):print("Hola, " + nombre + ", funcion 2")def funcion3_del_modulo(nombre):print("Hola, " + nombre + ", funcion 3")
Writing introduccion_python/modulo2.py
from introduccion_python.modulo2 import funcion2_del_modulofuncion2_del_modulo('MaximoFN')
Hola, MaximoFN, funcion 2
We can not only use modules created by us, but also installed modules (built-in modules
).
For example, we can use the platform
module
import platformx = platform.system()x
'Linux'
10.1. Entry points: files as modules and not as scripts
Now let's create a file called modulo3.py
%%writefile introduccion_python/modulo3.pyprint("Hola desde modulo3")def funcion_del_modulo():return "Hola desde la función del modulo3"
Overwriting introduccion_python/modulo3.py
If we now import modulo3.py
to use the funcion_del_modulo
function, let's see what happens.
import introduccion_python.modulo3 as mod3print(mod3.funcion_del_modulo())
Hola desde modulo3Hola desde la función del modulo3
We see that the print
from modulo3.py
has been executed, but that's not what we wanted. This is because when the file is named modulo3.py
, Python runs it as a script.
But what if we want to run introduccion_python/main.py
as a script?
!python introduccion_python/modulo3.py
Hola desde modulo3
We see that only the print
is executed, but not the function funcion_del_modulo
. If we want the duality of functionality of the file modulo3.py
, that is, to be able to import it from another module without it executing as a script and to run it standalone and execute the function we want, we use an entry point
. That is, using the condition if __name__ == '__main__':
and then specifying what we want to execute. Let's see this with an example, I will rewrite the modulo3.py
file.
%%writefile introduccion_python/modulo3.pyprint("Hola desde modulo3")def funcion_del_modulo():return "Hola desde la función del modulo3"if __name__ == "__main__":funcion_del_modulo()
Overwriting introduccion_python/modulo3.py
If I now call main.py
from another module, the print
will no longer be executed.
import introduccion_python.modulo3 as mod3print(mod3.funcion_del_modulo())
Hola desde la función del modulo3
And if I run it as a standalone script, the function funcion_del_modulo
will be executed.
!python introduccion_python/modulo3.py
Hola desde modulo3
11. Packages
In Python we can create our own packages. To do this, we create a folder with the package name.
!mkdir mi_paquete_de_python
We now create two files inside
!touch mi_paquete_de_python/modulo1.py mi_paquete_de_python/modulo2.py
And we write in them
%%writefile mi_paquete_de_python/modulo1.pydef funcion1():print("Hola desde la función 1 del módulo 1")def funcion2():print("Hola desde la función 2 del módulo 1")
Overwriting mi_paquete_de_python/modulo1.py
%%writefile mi_paquete_de_python/modulo2.pydef funcion1():print("Hola desde la función 1 del módulo 2")def funcion2():print("Hola desde la función 2 del módulo 2")
Overwriting mi_paquete_de_python/modulo2.py
Now we can call the functions from our package
from mi_paquete_de_python import modulo1 as mod1from mi_paquete_de_python import modulo2 as mod2mod1.funcion1()mod1.funcion2()mod2.funcion1()mod2.funcion2()
Hola desde la función 1 del módulo 1Hola desde la función 2 del módulo 1Hola desde la función 1 del módulo 2Hola desde la función 2 del módulo 2
But what if our package has dozens of files with functions that we want to use, would we have to import all the files one by one? To avoid this, we can create an __init__.py
file within the package where all these file imports can be handled.
!touch mi_paquete_de_python/__init__.py
%%writefile mi_paquete_de_python/__init__.pyimport modulo1import modulo2
Overwriting mi_paquete_de_python/__init__.py
Now we can only import our package, which internally has already imported all the modules
import mi_paquete_de_python as mi_paquetemi_paquete.modulo1.funcion1()mi_paquete.modulo1.funcion2()mi_paquete.modulo2.funcion1()mi_paquete.modulo2.funcion2()
Hola desde la función 1 del módulo 1Hola desde la función 2 del módulo 1Hola desde la función 1 del módulo 2Hola desde la función 2 del módulo 2
This way we only have to do an import
12. Try... except
When an error, or an exception as it is actually called, occurs, Python will normally catch it and generate an error message.
These exceptions can be handled using the try
and except
statements.
try:print(variable_no_declarada)except:print("Ha ocurrido una excepción")
Ha ocurrido una excepción
Since the try
block raises an error, the except
block will be executed.
Without the try
block, the program would freeze and generate an error.
As many exception blocks as desired can be defined, for example, if a special block of code is to be executed for a special type of error.
try:print(variable_no_declarada)except NameError:print("La variable \'variable_no_declarada\' no está definida")except:print("Algo inesperado ha ocurrido")
La variable 'variable_no_declarada' no está definida
The word else
can be used to indicate the case where no error has occurred.
try:print('MaximoFN')except NameError:print("Ha ocurrido una excepción")else:print('Todo OK')
MaximoFNTodo OK
with the finally
keyword, the code will be executed at the end whether an exception occurred or not
try:print(variable_no_declarada)except:print("Ha ocurrido una excepción")finally:print("'try except' finallizado")
Ha ocurrido una excepción'try except' finallizado
This can be useful for closing objects and cleaning up resources
class Clase:variable = 'MaximoFN'objeto = Clase()try:print(Clase.mi_variable)except:print("Ha ocurrido una excepción")finally:del objeto
Ha ocurrido una excepción
12.1. Create an exception
As a Python developer, you can choose to raise an exception if a condition occurs.
To raise (or generate) an exception, you need to use the keyword raise
def division(numerador, denominador):if denominador == 0:raise Exception("El denominador no puede ser 0")return numerador/denominadorprint(division(10, 0))
---------------------------------------------------------------------------Exception Traceback (most recent call last)<ipython-input-16-33fb6066fa78> in <module>5 return numerador/denominador6----> 7 print(division(10, 0))<ipython-input-16-33fb6066fa78> in division(numerador, denominador)1 def division(numerador, denominador):2 if denominador == 0:----> 3 raise Exception("El denominador no puede ser 0")45 return numerador/denominadorException: El denominador no puede ser 0
You can define what type of error to generate and the text that will be displayed to the user.
def division(numerador, denominador):if denominador == 0:raise TypeError("El denominador no puede ser 0")return numerador/denominadorprint(division(10, 0))
---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-17-26bfa63ae44c> in <module>5 return numerador/denominador6----> 7 print(division(10, 0))<ipython-input-17-26bfa63ae44c> in division(numerador, denominador)1 def division(numerador, denominador):2 if denominador == 0:----> 3 raise TypeError("El denominador no puede ser 0")45 return numerador/denominadorTypeError: El denominador no puede ser 0
13. Keywords or reserved words
Throughout this post, several occasions have featured Python reserved words or keywords
, these are a series of words reserved by Python
Below is a list of the keywords
import keywordkeyword.kwlist
['False','None','True','and','as','assert','async','await','break','class','continue','def','del','elif','else','except','finally','for','from','global','if','import','in','is','lambda','nonlocal','not','or','pass','raise','return','try','while','with','yield']
14. The ZEN of Python
By importing the this
module we can read the zen
of Python, that is, its philosophy or principles.
import this
The Zen of Python, by Tim PetersBeautiful is better than ugly.Explicit is better than implicit.Simple is better than complex.Complex is better than complicated.Flat is better than nested.Sparse is better than dense.Readability counts.Special cases aren't special enough to break the rules.Although practicality beats purity.Errors should never pass silently.Unless explicitly silenced.In the face of ambiguity, refuse the temptation to guess.There should be one-- and preferably only one --obvious way to do it.Although that way may not be obvious at first unless you're Dutch.Now is better than never.Although never is often better than *right* now.If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.Namespaces are one honking great idea -- let's do more of those!