Introducci贸n a Python
1. Resumen
Vamos a hacer una breve introducci贸n a Python, explicando los tipos de datos que tenemos, los operadores, el uso de funciones y de clases. Adem谩s, veremos c贸mo usar los objetos iterables, c贸mo usar m贸dulos, etc.
2. Tipos de datos de Python
Existen 7 tipos de datos en Python
- De tipo texto:
str
- Num茅ricos:
int
,float
,complex
- Secuencias:
list
,tuple
,range
- Mapping:
dict
- Sets:
set
,frozenset
- Booleanos:
bool
- Binarios:
bytes
,bytearray
,memoryview
Podemos obtener el tipo de dato mediante la funci贸n type()
type(5.)
float
Python es un lenguaje de tipado din谩mico, es decir, puedes tener una variable de un tipo y luego asignarle otro tipo
a = 5type(a)
int
a = 'MaximoFN'type(a)
str
Python tipa las variables por ti, pero si las quieres tipear t煤 se puede hacer
b = int(5.1)type(b), b
(int, 5)
Aunque b
se ha inicializado como 5.1
, es decir, deber铆a ser de tipo float
, al tiparlo nosotros a tipo int
, vemos que es de tipo int
y adem谩s su valor es 5
2.1. Strings
Los strings
son cadenas de caracteres, estas se pueden definir con doble comilla "
o comilla simple '
string = "MaximoFN"string
'MaximoFN'
string = 'MaximoFN'string
'MaximoFN'
Para escribir un string
muy largo y no tener una fila que ocupe mucho espacio, se puede introducir en varias l铆neas
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'
Sin embargo, vemos que en medio ha metido el car谩cter , este car谩cter indica el salto de l铆nea. Si usamos la funci贸n
print()
veremos c贸mo ya no aparece
print(string)
Este es un ejemplo decomo estoy introduciendo un stringen varias lineas
Como hemos dicho, los strings son cadenas de caracteres, por lo que podemos navegar e iterar a trav茅s de ellos
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
Podemos obtener la longitud de nuestro string mediante la funci贸n len()
len(string)
73
Chequear si hay alg煤n string determinado dentro del nuestro
'ejemplo' in string
True
Los strings tienen ciertos atributos 煤tiles, como poner todo en may煤sculas
print(string.upper())
ESTE ES UN EJEMPLO DECOMO ESTOY INTRODUCIENDO UN STRINGEN VARIAS LINEAS
Todo en min煤sculas
print(string.lower())
este es un ejemplo decomo estoy introduciendo un stringen varias lineas
Reemplazar caracteres
print(string.replace('o', '@'))
Este es un ejempl@ dec@m@ est@y intr@duciend@ un stringen varias lineas
Obtener todas las palabras
print(string.split())
['Este', 'es', 'un', 'ejemplo', 'de', 'como', 'estoy', 'introduciendo', 'un', 'string', 'en', 'varias', 'lineas']
Puedes ver todos los m茅todos de los strings en este enlace
Otra cosa 煤til que se puede hacer con los strings es concatenarlos
string1 = 'Maximo'string2 = 'FN'string1 + string2
'MaximoFN'
Antes explicamos que el car谩cter \n
correspond铆a a un salto de l铆nea, este car谩cter especial corresponde a una serie de caracteres especiales llamados Escape Characters
. Veamos otros
Si declaramos un string con doble comilla y queremos a帽adir una doble comilla dentro del string usamos el escape character \"
print("Este es el blog de \"MaximoFN\"")
Este es el blog de "MaximoFN"
Lo mismo con la comilla simple, a帽adimos \'
print('Este es el blog de \'MaximoFN\'')
Este es el blog de 'MaximoFN'
Ahora tenemos el problema de si queremos a帽adir el car谩cter \ ya que como hemos visto es un escape character
, as铆 que lo solucionamos poniendo doble barra (backslash) \
print('Este es el blog de \\MaximoFN\\')
Este es el blog de \MaximoFN\
Ya vimos antes el escape character
de nueva l铆nea \n
print('Este es el blog de \nMaximoFN')
Este es el blog deMaximoFN
Si queremos escribir desde el inicio de l铆nea a帽adimos \r
print('Esto no se imprimir谩 \rEste es el blog de MaximoFN')
Este es el blog de MaximoFN
Si queremos a帽adir un espacio grande (sangr铆a) usamos \t
print('Este es el blog de \tMaximoFN')
Este es el blog de MaximoFN
Podemos borrar un car谩cter con \b
print('Este es el blog de \bMaximoFN')
Este es el blog deMaximoFN
Podemos a帽adir el c贸digo ASCII en octal mediante \ooo
print('\115\141\170\151\155\157\106\116')
MaximoFN
O a帽adir el c贸digo ASCII en hexadecimal mediante \xhh
print('\x4d\x61\x78\x69\x6d\x6f\x46\x4e')
MaximoFN
Por 煤ltimo, podemos convertir otro tipo de dato en un string
n = 5print(type (n))string = str(n)print(type(string))
<class 'int'><class 'str'>
2.2. N煤meros
2.2.1. Enteros
N煤meros de tipo entero
n = 5n, type(n)
(5, int)
2.2.2. Float
N煤meros de tipo coma flotante
n = 5.1n, type(n)
(5.1, float)
2.2.3. Complejos
N煤meros complejos
n = 3 + 5jn, type(n)
((3+5j), complex)
2.2.4. Conversi贸n
Se puede convertir entre tipos de n煤meros
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)
No se puede convertir un n煤mero complex
a tipo int
o tipo float
2.3. Secuencias
2.3.1. Listas
Las listas guardan m煤ltiples 铆tems en una variable. Se declaran mediante los s铆mbolos []
, con los 铆tems separados por comas
lista = ['item0', 'item1', 'item2', 'item3', 'item4', 'item5']lista
['item0', 'item1', 'item2', 'item3', 'item4', 'item5']
Podemos obtener la longitud de una lista mediante la funci贸n len()
len(lista)
6
Las listas pueden tener 铆tems de distintos tipos
lista = ['item0', 1, True, 5.3, "item4", 5, 6.6]lista
['item0', 1, True, 5.3, 'item4', 5, 6.6]
En Python se empieza a contar desde la posici贸n 0, es decir, si queremos obtener el primer elemento de la lista
lista[0]
'item0'
Pero una de las cosas potentes de Python es que si queremos acceder a la 煤ltima posici贸n podemos usar 铆ndices negativos
lista[-1]
6.6
Si en vez de la 煤ltima posici贸n de la lista queremos la pen煤ltima
lista[-2]
5
Si solo queremos un rango de valores, por ejemplo, del segundo al quinto 铆tem accedemos mediante [2:5]
lista[2:5]
[True, 5.3, 'item4']
Si se omite el primer n煤mero del rango significa que queremos desde el primer 铆tem de la lista hasta el 铆tem indicado, es decir, si queremos desde el primer 铆tem hasta el quinto usamos [:5]
lista[:5]
['item0', 1, True, 5.3, 'item4']
Si se omite el 煤ltimo n煤mero del rango, significa que queremos desde el 铆tem indicado hasta el 煤ltimo. Es decir, si queremos desde el tercer 铆tem hasta el 煤ltimo, usamos [3:]
lista[3:]
[5.3, 'item4', 5, 6.6]
Podemos escoger el rango de 铆tems tambi茅n con n煤meros negativos, es decir, si queremos desde el antepen煤ltimo hasta el pen煤ltimo usamos [-3:-1]
. Esto es 煤til cuando se tiene listas que no se sabe su longitud, pero se sabe que se quiere un rango de valores del final, porque por ejemplo, la lista se ha creado con medidas que se van tomando y se quiere saber las 煤ltimas medias
lista[-3:-1]
['item4', 5]
Se puede comprobar si un 铆tem est谩 en la lista
'item4' in lista
True
2.3.1.1. Editar listas
Las listas en Python son din谩micas, es decir, se pueden modificar. Por ejemplo se puede modificar el tercer 铆tem
lista[2] = Falselista
['item0', 1, False, 5.3, 'item4', 5, 6.6]
Tambi茅n se puede modificar un rango de valores
lista[1:4] = [1.1, True, 3]lista
['item0', 1.1, True, 3, 'item4', 5, 6.6]
Se pueden agregar valores al final de la lista mediante el m茅todo append()
lista.append('item7')lista
['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item7']
O podemos insertar un valor en una posici贸n determinada mediante el m茅todo insert()
lista.insert(2, 'insert')lista
['item0', 1.1, 'insert', True, 3, 'item4', 5, 6.6, 'item7']
Se pueden unir listas mediante el m茅todo extend()
lista2 = ['item8', 'item9']lista.extend(lista2)lista
['item0', 1.1, 'insert', True, 3, 'item4', 5, 6.6, 'item7', 'item8', 'item9']
No es necesario extender la lista mediante otra lista, se puede hacer mediante otro tipo de dato iterable de Python (tuplas
, sets
, diccionarios
, etc)
tupla = ('item10', 'item11')lista.extend(tupla)lista
['item0',1.1,'insert',True,3,'item4',5,6.6,'item7','item8','item9','item10','item11']
Podemos eliminar una posici贸n determinada mediante el m茅todo pop()
lista.pop(2)lista
['item0',1.1,True,3,'item4',5,6.6,'item7','item8','item9','item10','item11']
Si no se especifica el 铆ndice, se elimina el 煤ltimo 铆tem
lista.pop()lista
['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item7', 'item8', 'item9', 'item10']
O se puede eliminar un item sabiendo su valor mediante el m茅todo remove()
lista.remove('item7')lista
['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item8', 'item9', 'item10']
Con la funci贸n del()
se puede eliminar tambi茅n un 铆tem de la posici贸n indicada
del lista[3]lista
['item0', 1.1, True, 'item4', 5, 6.6, 'item8', 'item9', 'item10']
Si no se indica el 铆ndice se elimina la lista completa
Con el m茅todo clear()
dejo la lista vac铆a
lista.clear()lista
[]
Se puede obtener la cantidad de 铆tems con un valor determinado mediante el m茅todo count()
lista = [5, 4, 6, 5, 7, 8, 5, 3, 1, 5]lista.count(5)
4
Tambi茅n se puede obtener el primer 铆ndice de un 铆tem con un valor determinado mediante el m茅todo index()
lista = [5, 4, 6, 5, 7, 8, 5, 3, 1, 5]lista.index(5)
0
2.3.1.2. List comprehension
Podemos operar a trav茅s de la lista
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']
Otras de las cosas potentes de Python son las list comprehensions
, que permiten hacer todo en una sola l铆nea y que el c贸digo quede m谩s compacto
fruits = ["apple", "banana", "cherry", "kiwi", "mango"]newlist = [x for x in fruits if "a" in x]newlist
['apple', 'banana', 'mango']
La sintaxis es la siguiente:
newlist = [expression for item in iterable if condition == True]
Se puede aprovechar para realizar operaciones en la lista original
newlist = [x.upper() for x in fruits if "a" in x]newlist
['APPLE', 'BANANA', 'MANGO']
2.3.1.3. Ordenar listas
Para ordenar listas usamos el m茅todo sort()
lista = [5, 8, 3, 4, 9, 5, 6]lista.sort()lista
[3, 4, 5, 5, 6, 8, 9]
Tambi茅n nos las ordena alfab茅ticamente
lista = ["orange", "mango", "kiwi", "pineapple", "banana"]lista.sort()lista
['banana', 'kiwi', 'mango', 'orange', 'pineapple']
A la hora de ordenar alfab茅ticamente, distingue entre may煤sculas y min煤sculas
lista = ["orange", "mango", "kiwi", "Pineapple", "banana"]lista.sort()lista
['Pineapple', 'banana', 'kiwi', 'mango', 'orange']
Se pueden ordenar en orden descendente mediante el atributo reverse = True
lista = [5, 8, 3, 4, 9, 5, 6]lista.sort(reverse = True)lista
[9, 8, 6, 5, 5, 4, 3]
Se pueden ordenar de la manera que queramos mediante el atributo key
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]
Se puede aprovechar esto para que, por ejemplo, a la hora de ordenar no distinga entre may煤sculas y min煤sculas
lista = ["orange", "mango", "kiwi", "Pineapple", "banana"]lista.sort(key = str.lower)lista
['banana', 'kiwi', 'mango', 'orange', 'Pineapple']
Se puede invertir la lista mediante el m茅todo reverse
lista = [5, 8, 3, 4, 9, 5, 6]lista.reverse()lista
[6, 5, 9, 4, 3, 8, 5]
2.3.1.4. Copiar listas
No se pueden copiar listas mediante lista1 = lista2
, ya que si se modifica lista1
tambi茅n se modifica lista2
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = lista1lista1[0] = Truelista2
[True, 8, 3, 4, 9, 5, 6]
Por lo que hay que usar el m茅todo copy()
lista1 = [5, 8, 3, 4, 9, 5, 6]lista2 = lista1.copy()lista1[0] = Truelista2
[5, 8, 3, 4, 9, 5, 6]
脫 hay que usar el constructor de listas 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. Concatenar listas
Se pueden concatenar listas mediante el operador +
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']
O mediante el m茅todo extend
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']
Otra forma de concatenar es repetir la tupla X veces mediante el operador *
lista1 = ['a', 'b', 'c']lista2 = lista1 * 3lista2
['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']
2.3.2. Tuplas
Las tuplas son similares a las listas, guardan m煤ltiples 铆tems en una variable, pueden contener 铆tems de distintos tipos, pero no se pueden modificar ni reordenar. Se definen mediante ()
, con los 铆tems separados por comas
Al no poderse modificar, hace que las tuplas se ejecuten un poco m谩s r谩pido que las listas, por lo que si no necesitas modificar los datos, es mejor utilizar tuplas en vez de listas
tupla = ('item0', 1, True, 3.3, 'item4', True)tupla
('item0', 1, True, 3.3, 'item4', True)
Se puede obtener su longitud mediante la funci贸n len()
len (tupla)
6
Para crear tuplas con un 煤nico elemento es necesario a帽adir una coma
tupla = ('item0',)tupla, type(tupla)
(('item0',), tuple)
Para acceder a un elemento de la tupla se procede igual que con las listas
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)
Podemos comprobar si hay un item en la tupla
'item4' in tupla
True
2.3.2.1. Modificar tuplas
Aunque las tuplas no son modificables, se pueden modificar convirti茅ndolas a listas, modificando la lista y despu茅s volver a convertirla en una tupla
lista = list(tupla)lista[4] = 'ITEM4'tupla = tuple(lista)tupla
('item0', 1, True, 3.3, 'ITEM4', True)
Al convertirla a lista, podemos hacer todas las modificaciones vistas en las listas
Lo que s铆 se puede es eliminar la tupla completa
del tuplaif 'tupla' not in locals():print("tupla eliminada")
tupla eliminada
2.3.2.2. Desempaquetar tuplas
Cuando creamos tuplas, en realidad estamos empaquetando datos
tupla = ('item0', 1, True, 3.3, 'item4', True)tupla
('item0', 1, True, 3.3, 'item4', True)
pero podemos desempaquetarlos
item0, item1, item2, item3, item4, item5 = tuplaitem0, item1, item2, item3, item4, item5
('item0', 1, True, 3.3, 'item4', True)
Si queremos sacar menos datos que la longitud de la tupla a帽adimos un *
item0, item1, item2, *item3 = tuplaitem0, item1, item2, item3
('item0', 1, True, [3.3, 'item4', True])
Se puede poner el asterisco *
en otra parte si por ejemplo lo que queremos es el 煤ltimo 铆tem
item0, item1, *item2, item5 = tuplaitem0, item1, item2, item5
('item0', 1, [True, 3.3, 'item4'], True)
2.3.2.3. Concatenar tuplas
Se pueden concatenar tuplas mediante el operador +
tupla1 = ("a", "b" , "c")tupla2 = (1, 2, 3)tupla3 = tupla1 + tupla2tupla3
('a', 'b', 'c', 1, 2, 3)
Otra forma de concatenar es repetir la tupla X veces mediante el operador *
tupla1 = ("a", "b" , "c")tupla2 = tupla1 * 3tupla2
('a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c')
2.3.2.4. M茅todos de las tuplas
Las tuplas tienen dos m茅todos, el primero es el m茅todo count()
que devuelve el n煤mero de veces que aparece un 铆tem dentro de la tupla
tupla = (5, 4, 6, 5, 7, 8, 5, 3, 1, 5)tupla.count(5)
4
Otro m茅todo es index()
que devuelve la primera posici贸n de un 铆tem dentro de la tupla
tupla = (5, 4, 6, 5, 7, 8, 5, 3, 1, 5)tupla.index(5)
0
2.3.3. Range
Con range()
podemos crear una secuencia de n煤meros, comenzando desde 0 (de forma predeterminada), se incrementa en 1 (de forma predeterminada) y se detiene antes de un n煤mero especificado
range(start, stop, step)
Por ejemplo, si queremos una secuencia de 0 a 5 (sin incluir el 5)
for i in range(5):print(f'{i} ', end='')
0 1 2 3 4
Si por ejemplo no queremos que empiece en 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
Por 煤ltimo, si no queremos que se incremente en 1, si por ejemplo queremos una secuencia de n煤meros pares.
for i in range(0, 10, 2):print(f'{i} ', end='')
0 2 4 6 8
2.4. Diccionarios
Los diccionarios se usan para guardar datos en pares key:value
. Son modificables, no ordenados y no permiten duplicidades. Se definen mediante los s铆mbolos {}
. Admiten 铆tems de distintos tipos de datos
diccionario = {"brand": "Ford","model": "Mustang","year": 1964,"colors": ["red", "white", "blue"]}diccionario
{'brand': 'Ford','model': 'Mustang','year': 1964,'colors': ['red', 'white', 'blue']}
Como se ha dicho no permiten duplicidades
diccionario = {"brand": "Ford","model": "Mustang","year": 1964,"year": 2000,"colors": ["red", "white", "blue"]}diccionario["year"]
2000
Se puede obtener su longitud mediante la funci贸n len()
len(diccionario)
4
Como se puede ver la longitud es 4 y no 5, ya que year
lo cuenta solo una vez
2.4.1. Acceder a los items
Para acceder a un elemento lo podemos hacer a trav茅s de su key
diccionario["model"]
'Mustang'
Tambi茅n se puede acceder mediante el m茅todo get
diccionario.get("model")
'Mustang'
Para saber todas las key
s de los diccionarios se puede usar el m茅todo keys()
diccionario.keys()
dict_keys(['brand', 'model', 'year', 'colors'])
Se puede usar una variable para apuntar a las key
s del diccionario, con lo que llam谩ndola una vez es necesario
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'])
Para obtener los valores del diccionario se puede usar el m茅todo values()
diccionario.values()
dict_values(['Ford', 'Mustang', 1964, 'white'])
Se puede usar una variable para apuntar a los values
s del diccionario, con lo que llam谩ndola una vez es necesario
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])
Si lo que se quiere son los item
s enteros, es decir key
s y value
s hay que usar el m茅todo items()
diccionario.items()
dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 2020)])
Se puede usar una variable para apuntar a los item
s del diccionario, con lo que llam谩ndola una vez es necesario
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)])
Se puede comprobar si una key
existe en el diccionario
"model" in diccionario
True
2.4.2. Modificar los 铆tems
Se puede modificar un item
accediendo a 茅l directamente
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario["year"] = 2020diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}
O se puede modificar mediante el m茅todo update()
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario.update({"year": 2020})diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}
2.4.3. A帽adir 铆tems
Se puede a帽adir un item
agreg谩ndolo de esta manera:
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se modifica un itemdiccionario["colour"] = "blue"diccionario
{'brand': 'Ford', 'model': 'Mustang', 'year': 1964, 'colour': 'blue'}
脫 se puede agregar mediante el m茅todo update()
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. Eliminar items
Se puede eliminar un item
con una key
espec铆fica mediante el m茅todo pop()
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina un itemdiccionario.pop("model")diccionario
{'brand': 'Ford', 'year': 1964}
O se puede eliminar un item
con una key
espec铆fica mediante del
indicando el nombre de la key
entre los s铆mbolos []
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina un itemdel diccionario["model"]diccionario
{'brand': 'Ford', 'year': 1964}
Se elimina el diccionario entero si se usa del
y no se especifica la key
de un item
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina un itemdel diccionarioif 'diccionario' not in locals():print("diccionario eliminado")
diccionario eliminado
Si lo que se quiere es eliminar el 煤ltimo item
introducido se puede usar el m茅todo popitem()
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}# Se elimina el 煤ltimo item introducidodiccionario.popitem()diccionario
{'brand': 'Ford', 'model': 'Mustang'}
Si se quiere limpiar el diccionario hay que usar el m茅todo clear()
diccionario = {"brand": "Ford","model": "Mustang","year": 1964}diccionario.clear()diccionario
{}
2.4.5. Copiar diccionarios
No se pueden copiar diccionarios mediante diccionario1 = diccionario2
, ya que si se modifica diccionario1
tambi茅n se modifica diccionario2
diccionario1 = {"brand": "Ford","model": "Mustang","year": 1964}diccionario2 = diccionario1diccionario1["year"] = 2000diccionario2["year"]
2000
Por lo que hay que usar el m茅todo copy()
diccionario1 = {"brand": "Ford","model": "Mustang","year": 1964}diccionario2 = diccionario1.copy()diccionario1["year"] = 2000diccionario2["year"]
1964
脫 hay que usar el constructor de diccionarios `dict()
diccionario1 = {"brand": "Ford","model": "Mustang","year": 1964}diccionario2 = dict(diccionario1)diccionario1["year"] = 2000diccionario2["year"]
1964
2.4.6. Diccionarios anidados
Los diccionarios pueden tener items
s de cualquier tipo de dato, incluso otros diccionarios. A este tipo de diccionarios se les denomina diccionarios nested
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. M茅todos de los diccionarios
Estos son los m茅todos que se pueden usar en los diccionarios
2.4.8. Dictionary comprehension
Igual que pod铆amos hacer list comprehensions
mediante la sintaxis
list_comprehension = [expression for item in iterable if condition == True]
Podemos hacer dictionaries comprehensions
mediante la siguiente sintaxis
dictionary_comprehension = {key_expression: value_expression for item in iterable if condition == True}```
Veamos un ejemplo
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
Los sets
se utilizan en Python para guardar un conjunto de items en una sola variable. Se pueden guardar items de distintos tipos. Son no ordenados y no tienen 铆ndice.
Se diferencian de las listas en que no tienen ni orden ni 铆ndice.
Se declaran mediante los s铆mbolos {}
Como set
es una palabra reservada en Python creamos un set
con el nombre set_
set_ = {'item0', 1, 5.3, "item4", 5, 6.6}set_
{1, 5, 5.3, 6.6, 'item0', 'item4'}
No puede haber 铆tems duplicados, si encuentra alg煤n 铆tem duplicado se queda solo con uno
set_ = {'item0', 1, 5.3, "item4", 5, 6.6, 'item0'}set_
{1, 5, 5.3, 6.6, 'item0', 'item4'}
Se puede obtener la longitud del set
mediante la funci贸n len()
len(set_)
6
Como se puede ver la longitud del set es 6 y no 7, ya que se queda con un solo 'item0'
Se puede comprobar si un item se encuentra en el set
'item4' in set_
True
2.5.1.1. A帽adir 铆tems
Se puede a帽adir un elemento al set mediante el m茅todo add()
set_.add(8.8)set_
{1, 5, 5.3, 6.6, 8.8, 'item0', 'item4'}
Se puede agregar otro set mediante el m茅todo `update()'
set2 = {"item5", "item6", 7}set_.update(set2)set_
{1, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6'}
Tambi茅n se pueden a帽adir items de tipos de datos iterables de 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. Eliminar 铆tems
Se puede eliminar un 铆tem determinado mediante el m茅todo remove()
set_.remove('item9')set_
{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6'}
O mediante el m茅todo discard()
set_.discard('item6')set_
{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5'}
Mediante el m茅todo pop()
se puede eliminar el 煤ltimo item, pero como los set
s no son ordenados no hay manera de saber cu谩l es el 煤ltimo item. El m茅todo pop()
devuelve el item eliminado
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
Mediante el m茅todo clear()
se puede vaciar el conjunto
set_.clear()set_
set()
Por 煤ltimo, con del
se puede eliminar el set
del set_if 'set_' not in locals():print("set eliminado")
set eliminado
2.5.1.3. Unir 铆tems
Una forma de unir sets es mediante el m茅todo union()
set1 = {"a", "b" , "c"}set2 = {1, 2, 3}set3 = set1.union(set2)set3
{1, 2, 3, 'a', 'b', 'c'}
Otra forma es mediante el m茅todo update()
, pero de esta manera se a帽ade un set en otro, no se crea uno nuevo
set1 = {"a", "b" , "c"}set2 = {1, 2, 3}set1.update(set2)set1
{1, 2, 3, 'a', 'b', 'c'}
Estos m茅todos de uni贸n eliminan los duplicados, pero si queremos obtener los elementos duplicados en dos sets usamos el m茅todo intersection()
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set3 = set1.intersection(set2)set3
{'apple'}
Si queremos obtener los elementos duplicados en dos sets, pero sin crear un set nuevo, usamos el m茅todo intersection_update()
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set1.intersection_update(set2)set1
{'apple'}
Ahora al rev茅s, si queremos quedarnos con los no duplicados usamos el m茅todo symmetric_difference()
.
La diferencia entre esto y la uni贸n entre dos sets es que en la uni贸n se queda con todos los 铆tems, pero los que est谩n duplicados solo los coge una vez. Ahora nos quedamos con los que no est谩n duplicados
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set3 = set1.symmetric_difference(set2)set3
{'banana', 'cherry', 'google', 'microsoft'}
Si queremos quedarnos con los no duplicados sin crear un nuevo set usamos el m茅todo symmetric_difference_update()
set1 = {"apple", "banana", "cherry"}set2 = {"google", "microsoft", "apple"}set1.symmetric_difference_update(set2)set1
{'banana', 'cherry', 'google', 'microsoft'}
2.5.1.4. M茅todos de los sets
Estos son los m茅todos que se pueden usar en los sets
2.5.2. FrozenSet
Los frozenset
s son como los set
s pero con la salvedad de que son inmutables, al igual que las tupla
s son como las list
s pero inmutables. Por lo que no podremos a帽adir o eliminar items
2.6. Booleanos
Hay solo dos booleanos en Python: True
y False
Mediante la funci贸n bool()
se puede evaluar si cualquier cosa es True
o False
print(bool("Hello"))print(bool(15))print(bool(0))
TrueTrueFalse
2.6.1. Otros tipos de datos True y False
Los siguientes datos son True
:* Cualquier string que no est茅 vac铆o* Cualquier n煤mero excepto el 0
- Cualquier lista, tupla, diccionario o set que no est茅 vac铆o
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. Binarios
2.7.1. Bytes
El tipo bytes
es una secuencia inmutable de bytes. Solo admiten caracteres ASCII. Tambi茅n se pueden representar los bytes mediante n煤meros enteros cuyos valores deben cumplir 0 <= x < 256
Para crear un tipo byte debemos introducir antes el car谩cter b
byte = b"MaximoFN"byte
b'MaximoFN'
Tambi茅n se pueden crear mediante su constructor bytes()
byte = bytes(10)byte
b' '
byte = bytes(range(10))byte
b' '
Se pueden concatenar bytes mediante el operador +
byte1 = b'DeepMax'byte2 = b'FN'byte3 = byte1 + byte2byte3
b'DeepMaxFN'
脫 mediante la repetici贸n con el operador *
byte1 = b'MaximoFN 'byte2 = byte1 * 3byte2
b'MaximoFN MaximoFN MaximoFN '
Podemos comprobar si un car谩cter est谩 dentro de la cadena
b'D' in byte1
False
Estos son los m茅todos que se pueden usar en los bytes
2.7.2. Bytearray
Los bytearray
s son iguales que los bytes
solo que son mutables
byte_array = bytearray(b'MaximoFN')byte_array
bytearray(b'MaximoFN')
2.7.3. MemoryView
Los objetos memoryview
permiten que el c贸digo Python acceda a los datos internos de un objeto que admite el protocolo de buffer sin realizar copias.
La funci贸n memoryview()
permite el acceso directo de lectura y escritura a los datos orientados a bytes de un objeto sin necesidad de copiarlos primero. Eso puede generar grandes ganancias de rendimiento cuando se opera con objetos grandes, ya que no crea una copia al cortar.
Protocolo de b煤fer, puede crear otro objeto de acceso para modificar los datos grandes sin copiarlos. Esto hace que el programa utilice menos memoria y aumente la velocidad de ejecuci贸n.
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. Operadores
3.1. Operadores aritm茅ticos
Operador suma +
3 + 5
8
Operador resta -
3 - 5
-2
Operador multiplicaci贸n *
3 * 5
15
Operador divisi贸n /
3 / 5
0.6
Operador m贸dulo %
. Devuelve el resto de una divisi贸n
25 % 2
1
Operador exponente **
5 ** 2
25
Operador divisi贸n entera //
25 // 2
12
3.2. Operadores de comparaci贸n
Operador es igual ==
1 == 1
True
Operador es diferente !=
1 != 2
True
Operador es mayor que >
3 > 2
True
Operador es menor que <
2 < 3
True
Operador es mayor o igual que >=
3 >= 3
True
Operador es menor o igual que <=
3 <= 3
True
3.3. Operadores l贸gicos
Operador and
True and True
True
Operador or
True or False
True
Operador not
not False
True
3.4. Operadores de identidad
Operador is
5.3 is 5.3
True
Operador is not
5.3 is not 5
True
3.5. Operadores de pertenencia
Operador in
x = ["apple", "banana"]"banana" in x
True
Operador not in
x = ["apple", "banana"]"orange" not in x
True
3.6. Operadores bit a bit
Operador AND &
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101c = a & b; # 12 = 0000 1100c
12
Operador OR |
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101c = a | b; # 61 = 0011 1101c
61
Operador XOR ^
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101c = a ^ b; # 49 = 0011 0001c
49
Operador NOT ~
a = 60 # 60 = 0011 1100c = ~a; # -61 = 1100 0011c
-61
Operador desplazamiento hacia la izquierda <<
a = 60 # 60 = 0011 1100c = a << 2; # 240 = 1111 0000c
240
Operador desplazamiento hacia la derecha >>
a = 60 # 60 = 0011 1100c = a >> 2; # 15 = 0000 1111c
15
3.7. Operadores de asignaci贸n
Operador `=
a = 5a
5
Operador +=
. x += y
es equivalente a x = x + y
a += 5a
10
Operador -=
. x -= y
es equivalente a `x = x - y
a -= 5a
5
Operador *=
. x *= y
es equivalente a `x = x * y
a *= 3a
15
Operador /=
. x /= y
es equivalente a `x = x / y
a /= 3a
5.0
Operador %=
. x %= y
es equivalente a `x = x % y
a = 25a %= 2a
1
Operador //=
. x //= y
es equivalente a `x = x // y
a = 25a //= 2a
12
Operador **=
. x **= y
es equivalente a `x = x ** y
a = 5a **= 2a
25
Operador &=
. x &= y
es equivalente a `x = x & y
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101a &= b; # 12 = 0000 1100a
12
Operador |=
. x |= y
es equivalente a x = x | y
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101a |= b; # 61 = 0011 1101a
61
Operador ^=
. x ^= y
es equivalente a `x = x ^ y
a = 60 # 60 = 0011 1100b = 13 # 13 = 0000 1101a ^= b; # 49 = 0011 0001a
49
Operador >>=
. x >>= y
es equivalente a `x = x >> y
a = 60 # 60 = 0011 1100a <<= 2; # 240 = 1111 0000a
240
Operador <<=
. x <<= y
es equivalente a x = x << y
a = 60 # 60 = 0011 1100a >>= 2; # 15 = 0000 1111a
15
4. Control de flujo
Para poder utilizar las herramientas de control de flujo es necesario a帽adir la sentencia, dos puntos :
y en una nueva l铆nea escribir el c贸digo con indentaci贸n.
A diferencia de otros lenguajes, Python necesita la indentaci贸n (a帽adir un espacio en blanco) para definir el c贸digo de dentro de una herramienta de control de flujo
4.1. If
Mediante if
podemos crear condicionales
if len('MaximoFN') == 8:print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
Si queremos crear m谩s de una condici贸n podemos usar elif
if len('MaximoFN') < 8:print('MaximoFN tiene menos de 8 caracteres')elif len('MaximoFN') == 8:print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
Si lo que queremos es que se ejecute algo en caso de que no se cumpla ninguna de las condiciones indicadas, podemos usar 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
Si queremos escribir todo en una sola l铆nea
if len('MaximoFN') == 8: print('MaximoFN tiene 8 caracteres')
MaximoFN tiene 8 caracteres
Igual, si queremos escribir todo en una l铆nea, pero con varias condiciones
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
Si por ejemplo queremos hacer la estructura del if
pero no queremos, de momento, codificar una de las condiciones, podemos usar 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
El bucle while
se ejecuta mientras la condici贸n sea True
i = 0string = 'MaximoFN'while len(string) > i:print(string[i], end='')i += 1
MaximoFN
Si queremos que el bucle pare por alguna condici贸n usamos break
i = 0string = 'MaximoFN'while len(string) > i:if string[i] == 'F':breakprint(string[i], end='')i += 1
Maximo
Si queremos que una de las iteraciones no se ejecute por alguna raz贸n usamos continue
i = 0string = 'Maximo FN'while len(string) > i:if string[i] == ' ':i += 1continueprint(string[i], end='')i += 1
MaximoFN
Mediante else
se puede ejecutar un bloque de c贸digo si la condici贸n del while
no es 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
El bucle for
se usa para ejecutar c贸digo mientras se itera por una secuencia, esta secuencia puede ser cualquier elemento iterable de Python (string
, lista
, tupla
, range
, diccionario
, 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
Tambi茅n se puede iterar por los set
s, pero como son elementos no ordenados, no tendremos control del orden de ejecuci贸n
set_ = {'M', 'a', 'x', 'i', 'm', 'o', 'F', 'N'}for x in set_:print(x, end='')
NximoaMF
Si queremos que el bucle pare por alguna condici贸n usamos break
string = 'MaximoFN'for x in string:if x == 'F':breakprint(x, end='')
Maximo
Si queremos que una de las iteraciones no se ejecute por alguna raz贸n usamos continue
string = 'Maximo FN'for x in string:if x == ' ':continueprint(x, end='')
MaximoFN
Mediante else
se puede ejecutar un bloque de c贸digo si la condici贸n del while
no es True
string = 'MaximoFN'for x in string:print(x, end='')else:print("\nSe ha terminado el for")
MaximoFNSe ha terminado el for
Si por ejemplo queremos hacer la estructura del for
pero no queremos, de momento, codificar su interior podemos usar pass
string = 'MaximoFN'for x in string:passprint('Interior del for no codificado')
Interior del for no codificado
5. Funciones
Una funci贸n es una porci贸n de c贸digo que se puede ejecutar tantas veces como quieras. Se le puede pasar argumentos y puede devolver datos como resultado
Para definir una funci贸n se comienza con la palabra reservada def
, seguido del nombre de la funci贸n, par茅ntesis ()
, dos puntos :
y a continuaci贸n en una nueva l铆nea indentado el c贸digo de la funci贸n
def funcion():print('MaximoFN')
Para llamar a la funci贸n solo es necesario escribir su nombre
funcion()
MaximoFN
A las funciones se les pueden pasar todos los argumentos que se quiera, dentro de los par茅ntesis y separados por comas
def funcion(string1, string2):print(string1 + ' ' + string2)funcion("Hola", "MaximoFN")
Hola MaximoFN
Cuando se llama a la funci贸n hay que pasarle el mismo n煤mero de argumentos que se han declarado, si se pasan m谩s o menos obtendr铆amos un error.
Si no sabemos los argumentos que va a recibir la funci贸n se puede usar *args
, es decir, poniendo un *
antes de los argumentos se indica que el n煤mero de argumentos es libre.
Al hacer esto, se le pasa una tupla
(recordemos que es inmutable) con los argumentos
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
En caso de no saber el orden de los argumentos de una funci贸n, podemos indicar el argumento que le queremos pasar indic谩ndole su nombre
def funcion(argumento1, argumento2, argumento3):print(argumento1 + ' '+ argumento2 + ' ' + argumento3)funcion(argumento3 = "MaximoFN", argumento1 = "Blog", argumento2 = "de")
Blog de MaximoFN
En caso de querer pasar los argumentos con su nombre, pero en caso de no saber cu谩ntos argumentos se van a pasar se puede usar **kwargs
. En este caso se le pasar谩 un diccionario con los argumentos
def funcion(**kargumentos):print("Autor del blog: " + kargumentos["autor"])funcion(blog = "Blog", pertenencia = "de", autor = "MaximoFN")
Autor del blog: MaximoFN
Si queremos que alg煤n argumento tenga un valor por defecto lo podemos indicar entre los par茅ntesis de la funci贸n. De esta manera, si a la hora de llamar a la funci贸n no se pasa dicho argumento, este en la funci贸n tendr谩 el valor por defecto
def funcion(argumento1, argumento2, argumento3 = "MaximoFN"):print(argumento1 + ' '+ argumento2 + ' ' + argumento3)funcion("Blog", "de")
Blog de MaximoFN
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
def funcion(argumento):longitud_lista = len(argumento)for i in range(longitud_lista):print(argumento[i], end=' ')funcion(["Blog", "de", "MaximoFN"])
Blog de MaximoFN
Las funciones pueden devolver datos, esto se hace mediante la palabra reservada 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
Pueden devolver m谩s de un dato
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
Si uno de los datos devueltos no nos interesa, podemos pasar de 茅l mediante `_
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
Si por ejemplo queremos hacer la estructura de la funci贸n pero no queremos, de momento, codificar el interior podemos usar pass
def funcion():passfuncion()
Una funci贸n puede llamarse a s铆 misma, a esto se le llama recursi贸n o recursividad de la funci贸n. Por ejemplo podemos usar esta cualidad para calcular el factorial de un n煤mero
def factorial(n):if n == 0 or n == 1:return 1else:return n * factorial(n-1)factorial(5)
120
5.1. Built in functions
Hay una serie de funciones ya definidas en Python que se pueden usar, como por ejemplo la funci贸n abs()
, que devuelve el valor absoluto
abs(-5)
5
A continuaci贸n se muestra una lista de estas funciones
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. Documentaci贸n de una funci贸n
Se puede a帽adir una explicaci贸n de una funci贸n que creemos mediante un comentario al inicio de la funci贸n, de esta manera cuando llamemos a la built in function
help()
nos mostrar谩 dicha explicaci贸n.
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
Otra opci贸n para ver la explicaci贸n de la funci贸n es usar el m茅todo __doc__
de la funci贸n
funcion.__doc__
'Esta es la explicaci贸n de la funci贸n'
5.3. Decoradores
Los decoradores son una funcionalidad de Python que permiten a帽adir caracter铆sticas nuevas a una funci贸n Se crea una funci贸n decoradora que tiene como par谩metro otra funci贸n. Entonces la funci贸n decoradora a帽ade la caracter铆stica nueva a la funci贸n que recibe
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==================
Pero otra manera m谩s potente de usar los decoradores es mediante el uso de @
y el nombre del decorador antes de la funci贸n.
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
y **kwargs
*args
y **kwargs
son argumentos opcionales que se pueden usar al definir una funci贸n en Python. La sintaxis es la siguiente:
def mi_funcion(arg1, arg2, *args, **kwargs):
# c贸digo de la funci贸n aqu铆
5.4.1. *args
*args
se usa para enviar un n煤mero variable de argumentos a una funci贸n. Al usar *args
, puedes enviar una cantidad variable de argumentos a la funci贸n sin tener que especificar el n煤mero exacto de argumentos que necesita la funci贸n. Los argumentos se reciben en la funci贸n como una tupla.
def saludo(saludo, *nombres):for nombre in nombres:print(f"{saludo}, {nombre}")saludo("Hola", "Alicia", "Roberto", "Carlos")
Hola, AliciaHola, RobertoHola, Carlos
5.4.2. **kwargs
**kwargs
se usa de la misma manera, pero para enviar un n煤mero variable de argumentos con palabras clave (keyword arguments
) a una funci贸n. Al usar **kwargs
, puedes enviar una cantidad variable de argumentos a la funci贸n y especificar el valor de cada argumento usando su nombre. Los argumentos se reciben en la funci贸n como un diccionario.
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. Funciones adicionales
6.1. Funciones lambda
Una funci贸n lambda es una peque帽a funci贸n an贸nima.
Una funci贸n lambda puede tomar cualquier n煤mero de argumentos, pero solo puede tener una expresi贸n.
Las funciones lambda se definen de la siguiente manera:
lambda arguments : expression```
x = lambda a : a + 10print(x(5))
15
x = lambda a, b, c : a + b + cprint(x(5, 6, 2))
13
El poder de lambda se muestra mejor cuando las usa como una funci贸n an贸nima dentro de otra funci贸n.
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. Funci贸n map
La funci贸n map
permite aplicar a cada elemento de una estructura iterable una funci贸n
lista = [1, 2, 3]def funcion_mas_1(valor):return valor + 1lista_modificada = list(map(funcion_mas_1, lista))lista_modificada
[2, 3, 4]
Esto es equivalente a usar list comprehension
lista_modificada = [funcion_mas_1(x) for x in lista]lista_modificada
[2, 3, 4]
6.3. Funci贸n filter
La funci贸n filter
permite seleccionar los elementos de una estructura iterable que cumplan con una condici贸n
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]
Esto es equivalente a usar list comprehension
lista_filtrada = [x for x in lista if esPar(x)]lista_filtrada
[2, 4, 6]
6.4. Funci贸n reduce
La funci贸n reduce
permite realizar tareas acumulativas sobre estructuras iterables
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. Funci贸n zip
Con la funci贸n zip
se puede combinar varias estructuras iterables en una sola, es decir permite agrupar varios elementos de las estructuras Ax en una sola estructura B. La estructura B est谩 formada por tuplas de los elementos de las estructuras Ax
nombres = ["Manolo", "Andres", "Fernando"]altura = [181, 178, 180]my_zip = list(zip(nombres, altura))my_zip
[('Manolo', 181), ('Andres', 178), ('Fernando', 180)]
6.5. Generadores
Supongamos que queremos iterar sobre una secuencia de n煤meros, pero de una manera especial que no nos ofrece ning煤n tipo de bucle. Esto lo podemos solucionar con los generadores. Para poder hacer esto, la funci贸n generadora no tiene que devolver el valor con return
, sino con yield
para que sepa que tiene que seguir iterando
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
Acabamos de hacer un iterador por n煤meros m煤ltiplos de 3
6.6. High order functions
Podemos crear funciones que reciben otras funciones como par谩metros, de manera que la funci贸n que recibe otra funci贸n como par谩metro se llama funci贸n de orden superior (high order function). Veamos un ejemplo
def increment(x):return x + 1def hof(f, x):return 2*f(x)print(hof(increment, 3))
8
7. Clases y objetos
Python es un lenguaje de programaci贸n orientado a objetos. Casi todo en Python es un objeto, con sus atributos y m茅todos. Una clase es como un constructor de objetos o un "plano" para crear objetos.
Para crear una clase se usa la palabra reservada class
class Clase:variable = 'MaximoFN'
Una vez creada la clase, se puede crear un objeto de dicha clase
objeto = Clase()Clase.variable
'MaximoFN'
Normalmente las clases tienen una funci贸n inicial, que se ejecuta cuando se crea un objeto de la clase. Esta funci贸n se denomina dunder init y se escribe __init__()
. A la funci贸n dunder init se le tiene que pasar siempre la variable self
, que indica la propia clase, y a continuaci贸n, las variables que se quiera pasar
Con esta funci贸n se suelen inicializar las variables de las clases, o se ejecuta el c贸digo que se necesita cuando se crea un objeto de la clase
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
Adem谩s de la funci贸n inicial dunder init, se pueden crear m谩s funciones. A estas funciones se les llama m茅todos de la clase. A estos m茅todos siempre hay que pasarles la variable self
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
La variable self
no tiene por qu茅 ser llamada self
, puede tener cualquier nombre, pero dentro de cada clase tiene que ser siempre el mismo. Pero por convenio se suele usar self
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
Se pueden modificar las variables de los objetos
objeto_persona.nombre = 'Marta'objeto_persona.saludar()
Hola mi nombre es Marta y tengo 36 a帽os
Incluso eliminarlas
del objeto_persona.nombre
Tambi茅n se puede eliminar el objeto entero
del objeto_persona
Si por ejemplo queremos hacer la estructura de la clase pero no queremos, de momento, codificar el interior podemos usar pass
class Persona:passobjeto_persona = Persona()
7.1. Herencia
La herencia nos permite definir una clase que herede todos los m茅todos y propiedades de otra clase.
La clase padre es la clase de la que se hereda, tambi茅n llamada clase base.
La clase hija es la clase que hereda de otra clase, tambi茅n llamada clase derivada.
Creamos una clase padre
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
Para crear la clase hija hay que indicar entre par茅ntesis, a la hora de declarar la clase, de qu茅 clase hereda
class Estudiante(Persona):pass
Y al momento de crear el objeto de la clase hija, se le pasan los par谩metros que la clase padre necesita
objeto_hijo = Estudiante("Mariano", "Sanz")objeto_hijo.imprimir_nombre()
Me llamo Mariano Sanz
Hasta ahora la clase hija ha heredado las funciones de la clase padre, pero podemos modificarlas reescribi茅ndolas. Por ejemplo reescribiendo la funci贸n dunder init.
Si se reescribe la funci贸n dunder init, si queremos que se llame a la funci贸n dunder init de la clase padre hay que llamarla.
Para esto hay dos maneras, una es mediante el nombre de la clase padre. En este caso, hay que pasarle la variable self
.
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
Otra forma es mediante super()
, en este caso no hace falta pasarle la variable self
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
Al modificar las funciones se puede agregar c贸digo nuevo
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
Por 煤ltimo, se pueden agregar nuevos m茅todos
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. Sobrecarga de operadores
Podemos definir operaciones b谩sicas, como la suma, entre varios objetos de una clase. Por ejemplo, si tenemos una clase que representa un vector, podemos definir la suma y la multiplicaci贸n entre objetos de dicha clase
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)
Todas las posibles sobrecargas de operadores son:
__add__(self, other)
: sobrecarga el operador de suma (+
).__sub__(self, other)
: sobrecarga el operador de resta (-
).*__mul__(self, other)
: sobrecarga el operador de multiplicaci贸n (*
).*__truediv__(self, other)
: sobrecarga el operador de divisi贸n (/
).*__floordiv__(self, other)
: sobrecarga el operador de divisi贸n de redondeo (//
). *__mod__(self, other)
: sobrecarga el operador de m贸dulo (%
).__divmod__(self, other)
: sobrecarga la funci贸ndivmod()
. *__pow__(self, other)
: sobrecarga el operador de potencia (**
).__lshift__(self, other)
: sobrecarga el operador de desplazamiento a la izquierda (<<
).__rshift__(self, other)
: sobrecarga el operador de desplazamiento a la derecha (>>
).*__and__(self, other)
: sobrecarga el operador de and (&
).*__or__(self, other)
: sobrecarga el operador de or (|
).*__xor__(self, other)
: sobrecarga el operador de xor (^
). *__lt__(self, other)
: sobrecarga el operador de comparaci贸n menor que (<
).__le__(self, other)
: sobrecarga el operador de comparaci贸n menor o igual que (<=
).*__eq__(self, other)
: sobrecarga el operador de comparaci贸n igual a (==
).*__ne__(self, other)
: sobrecarga el operador de comparaci贸n diferente a (!=
).*__gt__(self, other)
: sobrecarga el operador de comparaci贸n mayor que (>
).*__ge__(self, other)
: sobrecarga el operador de comparaci贸n mayor o igual que (>=
).*__neg__(self)
: sobrecarga el operador de negaci贸n (-
).*__pos__(self)
: sobrecarga el operador de posici贸n (+
). *__abs__(self)
: sobrecarga la funci贸nabs()
.__invert__(self)
: sobrecarga el operador de inversi贸n (~
).*__complex__(self)
: sobrecarga la funci贸ncomplex()
. *__int__(self)
: sobrecarga la funci贸nint()
.__float__(self)
: sobrecarga la funci贸nfloat()
.
7.3. Iteradores personalizados
Como hemos visto en el apartado 2 (Tipos de datos de Python), existen algunos tipos de datos sobre los que se puede iterar. Pero podemos hacernos nuestra propia clase iterable, siempre que tenga las funciones __len__
y __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
Ahora podemos iterar con el objeto de nuestra clase con bucles for
, por ejemplo
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. Llamada a objetos como funciones
Nos puede interesar llamar a un objeto de una funci贸n como si fuera una clase. Esto se puede conseguir agregando la funci贸n __call__
a la clase
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. Atributos y funciones privados
Cuando creamos una clase, podemos hacer que algunos atributos o funciones sean privados y no se pueda acceder desde fuera de la clase, para ello hay que a帽adir __
antes del atributo o m茅todo
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. Iteradores
Un iterador es un objeto que contiene un n煤mero contable de valores. Un iterador es un objeto sobre el que se puede iterar, lo que significa que puede recorrer todos los elementos. T茅cnicamente, en Python, un iterador es un objeto que implementa el protocolo del iterador, que consta de los m茅todos iter() y next().
Las listas
, tuplas
, diccionarios
y conjuntos
son todos objetos iterables. Son contenedores iterables de los que se puede obtener un iterador.
Todos estos objetos tienen un m茅todo iter()
que se usa para obtener un iterador:
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
El bucle for
en realidad crea un objeto iterador y ejecuta el m茅todo next()
en cada iteraci贸n.
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. Crear un objeto iterador
Para crear un objeto/clase como iterador, hay que implementar los m茅todos __iter__()
y __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
El ejemplo anterior continuar铆a para siempre si tuviera suficientes llamadas a next()
, o si se usara en un bucle for
.
Para evitar que la iteraci贸n contin煤e para siempre, podemos usar la declaraci贸n StopIteration
.
En el m茅todo __next__()
, podemos agregar una condici贸n de terminaci贸n para generar un error si la iteraci贸n se realiza un n煤mero espec铆fico de veces:
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. Iterar obteniendo el 铆ndice y el valor
Podemos iterar por un objeto iterable obteniendo en cada iteraci贸n su 铆ndice y su valor mediante el m茅todo enumerate()
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. Iterar simult谩neamente sobre dos objetos iterables
Si tenemos dos objetos iterables, de la misma longitud, podemos iterar por los dos a la vez mediante el m茅todo zip()
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. Alcance de variables
Una variable solo est谩 disponible dentro de la regi贸n en la que se crea. A esto se le llama alcance
9.1. Alcance local
Una variable creada dentro de una funci贸n pertenece al 谩mbito local de esa funci贸n y solo se puede usar dentro de esa funci贸n.
def funcion():x = 300print(x)funcion()
300
La variable x
no est谩 disponible fuera de la funci贸n, pero est谩 disponible para cualquier funci贸n dentro de ella
def funcion():x = 300def funcion_interna():print(x)funcion_interna()funcion()
300
9.2. Alcance global
Una variable creada en el cuerpo principal del c贸digo Python es una variable global y pertenece al 谩mbito global.
Las variables globales est谩n disponibles desde cualquier 谩mbito, global y local.
x = 300def funcion():print(f'脕mbito local: {x}')funcion()print(f'脕mbito global: {x}')
脕mbito local: 300脕mbito global: 300
Si se crean dos variables, una global y otra local, las dos con el mismo nombre, Python las crear谩 como dos variables distintas
x = 300def funcion():x = 200print(f'Variable local: {x}')funcion()print(f'Variable global: {x}')
Variable local: 200Variable global: 300
Si se necesita crear una variable global, pero est谩 declarada en el 谩mbito local, se puede usar la palabra clave global
.
La palabra clave global
hace que la variable sea global.
def funcion():global xx = 300funcion()print(f'Variable global: {x}')
Variable global: 300
Adem谩s, el uso de la palabra clave global
permite realizar un cambio en una variable global dentro de una funci贸n.
x = 300def funcion():global xx = 200funcion()print(f'Variable global: {x}')
Variable global: 200
10. M贸dulos
Un m贸dulo es un archivo que contiene un conjunto de funciones que desea incluir en su aplicaci贸n.
Para crear un m贸dulo, simplemente guarde el c贸digo que desea en un archivo con la extensi贸n de archivo .py
Tip: En los cuadernos Jupyter (Colab es un cuaderno Jupyter en l铆nea) si escribimos el car谩cter
!
antes de un comando podremos ejecutar comandos de terminal
Primero vamos a ver en qu茅 directorio estamos, para eso usamos el comando pwd
(print working directory)
!pwd
/home/wallabot/Documentos/web/portafolio/posts
Vamos a crear una carpeta para crear nuestros m贸dulos con el comando mkdir
(make directory)
!mkdir introduccion_python
A continuaci贸n veamos qu茅 archivos hay en nuestra carpeta. Esto lo haremos mediante el comando ls
(list)
!ls introduccion_python
Vemos que est谩 vac铆a, creamos un nuevo archivo .py
en el que vamos a crear nuestro m贸dulo
%%writefile introduccion_python/modulo1.pydef funcion_del_modulo(nombre):print("Hola, " + nombre)
Writing introduccion_python/modulo1.py
Volvemos a ver qu茅 archivos hay en nuestra carpeta
!ls introduccion_python
modulo1.py __pycache__
Vemos que se ha creado un archivo modulo1.py
. Ya podemos usarlo
Para usar un m贸dulo externo hay que usar la palabra import
. Para usar las funciones del m贸dulo hay que poner primero el nombre del m贸dulo, un .
y a continuaci贸n el nombre de la funci贸n que se quiere usar
import introduccion_python.modulo1introduccion_python.modulo1.funcion_del_modulo('MaximoFN')
Hola, MaximoFN
Si queremos que dentro de nuestro c贸digo, el m贸dulo tenga un nombre determinado podemos usar la palabra as
import introduccion_python.modulo1 as mod1mod1.funcion_del_modulo('MaximoFN')
Hola, MaximoFN
Si el m贸dulo tiene varias funciones, pero solo queremos importar una, podemos hacerlo mediante el uso de las palabras from
e import
. La forma ser铆a
from <modulo> import <funcion>```
En este caso no hace falta indicar el nombre del m贸dulo al llamar a la funci贸n
%%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
No solo podemos usar m贸dulos creados por nosotros, sino m贸dulos ya instalados (built-in modules
)
Por ejemplo podemos usar el m贸dulo platform
import platformx = platform.system()x
'Linux'
10.1. Entry points: archivos como m贸dulos y no como scripts
Vamos ahora a crear un archivo llamado 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
Si ahora importamos modulo3.py
para usar la funci贸n funcion_del_modulo
veamos qu茅 ocurre
import introduccion_python.modulo3 as mod3print(mod3.funcion_del_modulo())
Hola desde modulo3Hola desde la funci贸n del modulo3
Vemos que se ha ejecutado el print
de modulo3.py
, pero no es lo que nosotros quer铆amos, esto es debido a que al llamarse el archivo modulo3.py
Python lo ejecuta como un script
Pero 驴qu茅 ocurre si queremos ejecutar introduccion_python/main.py
como un script?
!python introduccion_python/modulo3.py
Hola desde modulo3
Vemos que solo se ejecuta el print
, pero no la funci贸n funcion_del_modulo
. Si queremos tener la dualidad de funcionalidad del archivo modulo3.py
, es decir, que podamos importarlo desde otro m贸dulo sin que se ejecute como un script y ejecutarlo solo y que se ejecute la funci贸n que nosotros queremos, se usa un entry point
. Esto es, usar la condici贸n if __name__ == '__main__':
y a continuaci贸n indicar qu茅 queremos que se ejecute. Ve谩moslo con un ejemplo, voy a reescribir el archivo modulo3.py
%%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
Si ahora llamo a main.py
desde otro m贸dulo, ya no se ejecutar谩 el print
import introduccion_python.modulo3 as mod3print(mod3.funcion_del_modulo())
Hola desde la funci贸n del modulo3
Y si lo ejecuto como un script independiente, se ejecutar谩 la funci贸n funcion_del_modulo
!python introduccion_python/modulo3.py
Hola desde modulo3
11. Paquetes
En Python podemos crearnos nuestros propios paquetes, para ello creamos una carpeta con el nombre del paquete
!mkdir mi_paquete_de_python
Creamos ahora dos archivos dentro
!touch mi_paquete_de_python/modulo1.py mi_paquete_de_python/modulo2.py
Y escribimos en ellos
%%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
Ahora podemos llamar a las funciones de nuestro paquete
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
Pero qu茅 ocurre si nuestro paquete tiene decenas de archivos con funciones que queremos usar, tendr铆amos que importar todos los archivos uno a uno. Para evitar esto, se puede crear un archivo __init__.py
dentro del paquete donde se haga toda esta importaci贸n de archivos
!touch mi_paquete_de_python/__init__.py
%%writefile mi_paquete_de_python/__init__.pyimport modulo1import modulo2
Overwriting mi_paquete_de_python/__init__.py
Ahora podemos solamente importar nuestro paquete, que ya internamente se han importado todos los m贸dulos
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
De esta manera solo tenemos que hacer un import
12. Try... except
Cuando ocurre un error, o una excepci贸n como se llama realmente, Python normalmente lo capturar谩 y generar谩 un mensaje de error.
Estas excepciones se pueden manejar usando las declaraciones try
y except
try:print(variable_no_declarada)except:print("Ha ocurrido una excepci贸n")
Ha ocurrido una excepci贸n
Dado que el bloque try
genera un error, entonces se ejecutar谩 el bloque except
Sin el bloque try
, el programa se bloquear铆a y generar铆a un error
Se pueden definir tantos bloques de excepci贸n como se desee, por ejemplo, si se quiere ejecutar un bloque de c贸digo especial para un tipo de error especial
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
Se puede usar la palabra else
para indicar el caso en el que no se haya producido un error
try:print('MaximoFN')except NameError:print("Ha ocurrido una excepci贸n")else:print('Todo OK')
MaximoFNTodo OK
con la palabra finally
se ejecutar谩 un c贸digo al final haya ocurrido una excepci贸n o no
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
Esto puede resultar 煤til para cerrar objetos y limpiar recursos
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. Crear una excepcion
Como desarrollador de Python, se puede elegir lanzar una excepci贸n si ocurre una condici贸n.
Para lanzar (o generar) una excepci贸n, hay que usar la palabra clave 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
Se puede definir qu茅 tipo de error generar y el texto que se mostrar谩 al usuario
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 o palabras reservadas
Durante este post en varias ocasiones han aparecido palabras reservadas de Python o keyword
s, estas son una serie de palabras reservadas por Python
A continuaci贸n se muestra una lista de las keyword
s
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. El ZEN de Python
Importando el m贸dulo this
podemos leer el zen
de Python, es decir, su filosof铆a o principios
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!