Introducción a Python

Python 🐍 es uno de los lenguajes de programación 💻 MÁS USADO. Entra y aprende todo lo que necesitas sobre Python 🐍

Índice

Open In Colab

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.

python

Existen 7 tipos de datos en Python

  1. De tipo texto:str
  2. Numéricos:int, float, complex
  3. Secuencias: list, tuple, range
  4. Mapping: dict
  5. Sets: set, frozenset
  6. Booleanos: bool
  7. Binarios: bytes, bytearray, memoryview

Podemos obtener el tipo de dato mediante la función type()

Code:

type(5.)

Output:

float

Python es un lenguaje de tipado dinámico, es decir puedes tener una variable de un tipo y luego asignarle otro tipo

Code:

a = 5

type(a)

Output:

int

Code:

a = 'MaximoFN'

type(a)

Output:

str

Python tipa las variables por ti, pero si las quieres tipar tu se puede hacer

Code:

b = int(5.1)

type(b), b

Output:

(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

Los strings son cadenas de caracteres, estos se pueden definir con doble comilla " o comilla simple '

Code:

string = "MaximoFN"

string

Output:

'MaximoFN'

Code:

string = 'MaximoFN'

string

Output:

'MaximoFN'

Para escribir un string muy largo y no tener una fila que ocupe mucho espacio se puede introducir en varias lineas

Code:

string = """Este es un ejemplo de

como estoy introduciendo un string

en varias lineas"""

string

Output:

'Este es un ejemplo de\ncomo estoy introduciendo un string\nen varias lineas'

Code:

string = '''Este es un ejemplo de

como estoy introduciendo un string

en varias lineas'''

string

Output:

'Este es un ejemplo de\ncomo estoy introduciendo un string\nen varias lineas'

Sin embargo vemos que en medio ha metido el caracter \n, este caracter indica el salto de linea. Si usamos la función print() veremos como ya no aparece

Code:

print(string)

Output:

Este es un ejemplo de

como estoy introduciendo un string

en varias lineas

Como hemos dicho los strings son cadenas de caracteres, por lo que podemos navegar e iterar a traves de ellos

Code:

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 linea

print(string[i], end='')

Output:

Este es un

Podemos obtener la longitud de nuestro string mediante la función len()

Code:

len(string)

Output:

73

Checkear si hay algun string determinado dentro del nuestro

Code:

'ejemplo' in string

Output:

True

Los strings tienen ciertos atributos útiles, como poner todo en mayusculas

Code:

print(string.upper())

Output:

ESTE ES UN EJEMPLO DE

COMO ESTOY INTRODUCIENDO UN STRING

EN VARIAS LINEAS

Todo en minúsculas

Code:

print(string.lower())

Output:

este es un ejemplo de

como estoy introduciendo un string

en varias lineas

Reemplazar caracteres

Code:

print(string.replace('o', '@'))

Output:

Este es un ejempl@ de

c@m@ est@y intr@duciend@ un string

en varias lineas

Obtener todas las palabras

Code:

print(string.split())

Output:

['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 util que se puede hacer con los strings es concatenarlos

Code:

string1 = 'Maximo'

string2 = 'FN'

string1 + string2

Output:

'MaximoFN'

Antes explicamos que el caracter \n correspondía a una salto de linea, este caracter 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 \"

Code:

print("Este es el blog de \"MaximoFN\"")

Output:

Este es el blog de "MaximoFN"

Lo mismo con la comilla simple, añadimos \'

Code:

print('Este es el blog de \'MaximoFN\'')

Output:

Este es el blog de 'MaximoFN'

Ahora tenemos el problema de si queremos añadir el caracter \ ya que como hemos visto es un escape character, así que lo solucionamos poniendo doble barra (backslash) \\

Code:

print('Este es el blog de \\MaximoFN\\')

Output:

Este es el blog de \MaximoFN\

Ya vimos antes el escape character de nueva linea \n

Code:

print('Este es el blog de \nMaximoFN')

Output:

Este es el blog de

MaximoFN

Si queremos escribir desde el inicio de linea añadimos \r

Code:

print('Esto no se imprimirá \rEste es el blog de MaximoFN')

Output:

Este es el blog de MaximoFN

Si queremos añadir añadir un espacio grande (sangría) usamos \t

Code:

print('Este es el blog de \tMaximoFN')

Output:

Este es el blog de MaximoFN

Podemos borrar un caracter con \b

Code:

print('Este es el blog de \bMaximoFN')

Output:

Este es el blog deMaximoFN

Podemos añadir el codigo ASCII en octal mediante \ooo

Code:

print('\115\141\170\151\155\157\106\116')

Output:

MaximoFN

O añadir el codigo ASCII en hexadecimal mediante \xhh

Code:

print('\x4d\x61\x78\x69\x6d\x6f\x46\x4e')

Output:

MaximoFN

Por último, podemos convertir otro tipo de dato a string

Code:

n = 5

print(type (n))

string = str(n)

print(type(string))

Output:

<class 'int'>

<class 'str'>

Numeros de tipo entero

Code:

n = 5

n, type(n)

Output:

(5, int)

Números de tipo de coma flotante

Code:

n = 5.1

n, type(n)

Output:

(5.1, float)

Números complejos

Code:

n = 3 + 5j

n, type(n)

Output:

((3+5j), complex)

Se puede convertir entre tipos de números

Code:

n = 5

n = float(n)

n, type(n)

Output:

(5.0, float)

Code:

n = 5.1

n = complex(n)

n, type(n)

Output:

((5.1+0j), complex)

Code:

n = 5.1

n = int(n)

n, type(n)

Output:

(5, int)

No se puede convertir un numero complex a tipo int o tipo float

Las listas guardan múltiples items en una variable. Se declaran mediante los símbolos [], con los items separados por comas

Code:

lista = ['item0', 'item1', 'item2', 'item3', 'item4', 'item5']

lista

Output:

['item0', 'item1', 'item2', 'item3', 'item4', 'item5']

Podemos obtener la longitud de una lista mediante la función len()

Code:

len(lista)

Output:

6

Las listas pueden tener items de distintos tipos

Code:

lista = ['item0', 1, True, 5.3, "item4", 5, 6.6]

lista

Output:

['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 la primera posición de la lista

Code:

lista[0]

Output:

'item0'

Pero una de las cosas potentes de Python es que si queremos acceder a la última posición podemos usar índices negativos

Code:

lista[-1]

Output:

6.6

Si en vez de la última posición de la lista queremos la penúltima

Code:

lista[-2]

Output:

5

Si solo queremos un rango de valores, por ejemplo, del segundo al quinto item accedemos mediante [2:5]

Code:

lista[2:5]

Output:

[True, 5.3, 'item4']

Si se omite el primer número del rango singnifica que queremos desde el primer item de la lista hasta el item indicado, es decir, si queremos desde el primer item hasta el quinto usamos [:5]

Code:

lista[:5]

Output:

['item0', 1, True, 5.3, 'item4']

Si se omite el último número del rango significa que queremos desde el item indicado hasta el último, es decir, si queremos desde el tercer item hasta el último usamos [3:]

Code:

lista[3:]

Output:

[5.3, 'item4', 5, 6.6]

Podemos escoger el rango de items 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

Code:

lista[-3:-1]

Output:

['item4', 5]

Se puede comprobar si un item está en la lista

Code:

'item4' in lista

Output:

True

Las listas en Python son dinámicas, es decir, se pueden modificar. Por ejemplo se puede modificar el tercer item

Code:

lista[2] = False

lista

Output:

['item0', 1, False, 5.3, 'item4', 5, 6.6]

También se puede modificat un rango de valores

Code:

lista[1:4] = [1.1, True, 3]

lista

Output:

['item0', 1.1, True, 3, 'item4', 5, 6.6]

Se pueden añadir valores al final de la lista mediante el método append()

Code:

lista.append('item7')

lista

Output:

['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()

Code:

lista.insert(2, 'insert')

lista

Output:

['item0', 1.1, 'insert', True, 3, 'item4', 5, 6.6, 'item7']

Se pueden unir listas mediante el método extend()

Code:

lista2 = ['item8', 'item9']

lista.extend(lista2)

lista

Output:

['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)

Code:

tupla = ('item10', 'item11')

lista.extend(tupla)

lista

Output:

['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()

Code:

lista.pop(2)

lista

Output:

['item0',

1.1,

True,

3,

'item4',

5,

6.6,

'item7',

'item8',

'item9',

'item10',

'item11']

Si no se especifica el indice se elimina el último item

Code:

lista.pop()

lista

Output:

['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()

Code:

lista.remove('item7')

lista

Output:

['item0', 1.1, True, 3, 'item4', 5, 6.6, 'item8', 'item9', 'item10']

Con la función del() se puede eliminar también un item de la posición indicada

Code:

del lista[3]

lista

Output:

['item0', 1.1, True, 'item4', 5, 6.6, 'item8', 'item9', 'item10']

Si no se indica el índice se elimina la lista entera

Con el método clear() deja la lista vacía

Code:

lista.clear()

lista

Output:

[]

Se puede obtener la cantidad de items con un valor determinado mediante el método count()

Code:

lista = [5, 4, 6, 5, 7, 8, 5, 3, 1, 5]

lista.count(5)

Output:

4

También se puede obtener el primer índice de un item con un valor determinado mediante el método index()

Code:

lista = [5, 4, 6, 5, 7, 8, 5, 3, 1, 5]

lista.index(5)

Output:

0

Podemos operar a través de la lista

Code:

fruits = ["apple", "banana", "cherry", "kiwi", "mango"]

newlist = []

# Iteramos por todos los items de la lista

for x in fruits:

# Si el item contiene el caracter "a" lo añadimos a newlist

if "a" in x:

newlist.append(x)

newlist

Output:

['apple', 'banana', 'mango']

Otras de las cosas potentes de Python son las list comprehension, que permiten hacer todo en una sola linea y que el código quede más compacto

Code:

fruits = ["apple", "banana", "cherry", "kiwi", "mango"]

newlist = [x for x in fruits if "a" in x]

newlist

Output:

['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

Code:

newlist = [x.upper() for x in fruits if "a" in x]

newlist

Output:

['APPLE', 'BANANA', 'MANGO']

Para ordenar listas usamos el método sort()

Code:

lista = [5, 8, 3, 4, 9, 5, 6]

lista.sort()

lista

Output:

[3, 4, 5, 5, 6, 8, 9]

También nos las ordena allfabéticamente

Code:

lista = ["orange", "mango", "kiwi", "pineapple", "banana"]

lista.sort()

lista

Output:

['banana', 'kiwi', 'mango', 'orange', 'pineapple']

A la hora de ordenar alfabéticamente distingue entre mayúsculas y minúsculas

Code:

lista = ["orange", "mango", "kiwi", "Pineapple", "banana"]

lista.sort()

lista

Output:

['Pineapple', 'banana', 'kiwi', 'mango', 'orange']

Se pueden ordenar en orden descendente mediante el atributo reverse = True

Code:

lista = [5, 8, 3, 4, 9, 5, 6]

lista.sort(reverse = True)

lista

Output:

[9, 8, 6, 5, 5, 4, 3]

Se pueden ordenar de la manera que queramos mediante el atributo key

Code:

def myfunc(n):

# devuelve el valor absoluto de n - 50

return abs(n - 50)

lista = [100, 50, 65, 82, 23]

lista.sort(key = myfunc)

lista

Output:

[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

Code:

lista = ["orange", "mango", "kiwi", "Pineapple", "banana"]

lista.sort(key = str.lower)

lista

Output:

['banana', 'kiwi', 'mango', 'orange', 'Pineapple']

Se puede voltear la lista mediante el método reverse

Code:

lista = [5, 8, 3, 4, 9, 5, 6]

lista.reverse()

lista

Output:

[6, 5, 9, 4, 3, 8, 5]

No se pueden copiar listas mediante lista1 = lista2, ya que si se modifica lista1 también se modifica lista2

Code:

lista1 = [5, 8, 3, 4, 9, 5, 6]

lista2 = lista1

lista1[0] = True

lista2

Output:

[True, 8, 3, 4, 9, 5, 6]

Por lo que hay que usar el método copy()

Code:

lista1 = [5, 8, 3, 4, 9, 5, 6]

lista2 = lista1.copy()

lista1[0] = True

lista2

Output:

[5, 8, 3, 4, 9, 5, 6]

O hay que usar el constructor de listas list()

Code:

lista1 = [5, 8, 3, 4, 9, 5, 6]

lista2 = list(lista1)

lista1[0] = True

lista2

Output:

[5, 8, 3, 4, 9, 5, 6]

Se pueden concatenar listas mediante el operador +

Code:

lista1 = [5, 8, 3, 4, 9, 5, 6]

lista2 = ['a', 'b', 'c']

lista = lista1 + lista2

lista

Output:

[5, 8, 3, 4, 9, 5, 6, 'a', 'b', 'c']

O mediante el método extend

Code:

lista1 = [5, 8, 3, 4, 9, 5, 6]

lista2 = ['a', 'b', 'c']

lista1.extend(lista2)

lista1

Output:

[5, 8, 3, 4, 9, 5, 6, 'a', 'b', 'c']

Otra forma de concatenar es repetir la tupla X veces mediante el operador *

Code:

lista1 = ['a', 'b', 'c']

lista2 = lista1 * 3

lista2

Output:

['a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c']

Las tuplas son similares a las listas, guardan múltiples items en una variable, pueden contener items de distintos tipos, pero no s epueden modificar, ni reordenar. Se definen mediante (), con los items 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

Code:

tupla = ('item0', 1, True, 3.3, 'item4', True)

tupla

Output:

('item0', 1, True, 3.3, 'item4', True)

Se puede obtener su longitud mediante la función len()

Code:

len (tupla)

Output:

6

Para crear tuplas con un único elemento es necesario añadir una coma

Code:

tupla = ('item0',)

tupla, type(tupla)

Output:

(('item0',), tuple)

Para acceder a un elemento de la tupla se procede igual que con las listas

Code:

tupla = ('item0', 1, True, 3.3, 'item4', True)

print(tupla[0])

print(tupla[-1])

print(tupla[2:4])

print(tupla[-4:-2])

Output:

item0

True

(True, 3.3)

(True, 3.3)

Podemos comprobar si hay un item en la tupla

Code:

'item4' in tupla

Output:

True

Aunque las tuplas no son modificables, se pueden modificar conviertiéndolas a listas, modificando la lista y después volviéndola a convertir a tupla

Code:

lista = list(tupla)

lista[4] = 'ITEM4'

tupla = tuple(lista)

tupla

Output:

('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 entera

Code:

del tupla

if 'tupla' not in locals():

print("tupla eliminada")

Output:

tupla eliminada

Cuando creamos tuplas, en realidad estamos empaquetando datos

Code:

tupla = ('item0', 1, True, 3.3, 'item4', True)

tupla

Output:

('item0', 1, True, 3.3, 'item4', True)

pero podemos desempaquetarlos

Code:

item0, item1, item2, item3, item4, item5 = tupla

item0, item1, item2, item3, item4, item5

Output:

('item0', 1, True, 3.3, 'item4', True)

Si queremos sacar menos datos que la longitud de la tupla añadimos un *

Code:

item0, item1, item2, *item3 = tupla

item0, item1, item2, item3

Output:

('item0', 1, True, [3.3, 'item4', True])

Se puede poner el asterisco * en otra parte si por ejemplo lo que queremos es el último item

Code:

item0, item1, *item2, item5 = tupla

item0, item1, item2, item5

Output:

('item0', 1, [True, 3.3, 'item4'], True)

Se pueden concatenar tuplas mediante el operador +

Code:

tupla1 = ("a", "b" , "c")

tupla2 = (1, 2, 3)

tupla3 = tupla1 + tupla2

tupla3

Output:

('a', 'b', 'c', 1, 2, 3)

Otra forma de concatenar es repetir la tupla X veces mediante el operador *

Code:

tupla1 = ("a", "b" , "c")

tupla2 = tupla1 * 3

tupla2

Output:

('a', 'b', 'c', 'a', 'b', 'c', 'a', 'b', 'c')

Las tuplas tienen dos métodos, el primero es el método count() que devuelve el número de veces que existe un item dentro de la tupla

Code:

tupla = (5, 4, 6, 5, 7, 8, 5, 3, 1, 5)

tupla.count(5)

Output:

4

Otro método es index() que devuelve la primera posición de un item dentro de la tupla

Code:

tupla = (5, 4, 6, 5, 7, 8, 5, 3, 1, 5)

tupla.index(5)

Output:

0

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)

Code:

for i in range(5):

print(f'{i} ', end='')

Output:

0 1 2 3 4

Si por ejemplo no queremos que empiece en 0

Code:

for i in range(2, 5):

print(f'{i} ', end='')

Output:

2 3 4

Code:

for i in range(-2, 5):

print(f'{i} ', end='')

Output:

-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úmero pares

Code:

for i in range(0, 10, 2):

print(f'{i} ', end='')

Output:

0 2 4 6 8

Los diccionarios se usan para guardar datos en pares key:data. Son modificables, no ordenados y no permiten duplicidades. Se definen mediante los símbolos {}. Admiten items de distintos tipos de datos

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964,

"colors": ["red", "white", "blue"]

}

diccionario

Output:

{'brand': 'Ford',

'model': 'Mustang',

'year': 1964,

'colors': ['red', 'white', 'blue']}

Como se ha dicho no permiten duplicidades

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964,

"year": 2000,

"colors": ["red", "white", "blue"]

}

diccionario["year"]

Output:

2000

Se puede obtener su longitud mediante la función len()

Code:

len(diccionario)

Output:

4

Como se puede ver la longitud es 4 y no 5, ya que year lo cuenta solo una vez

Para acceder a un item lo podemos hacer a través de su key

Code:

diccionario["model"]

Output:

'Mustang'

También se puede acceder mediante el método get()

Code:

diccionario.get("model")

Output:

'Mustang'

Para saber todas las keys de los diccionarios se puede usar el método keys()

Code:

diccionario.keys()

Output:

dict_keys(['brand', 'model', 'year', 'colors'])

Se puede usar una variable para apuntar a las keys del diccionario, con lo que llamándola una vez es necesario

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se declara una vez la variable que apunta a las keys

x = diccionario.keys()

print(x)

# Se añade una nueva key

diccionario["color"] = "white"

# Se consulta la variable que apunta a las key

print(x)

Output:

dict_keys(['brand', 'model', 'year'])

dict_keys(['brand', 'model', 'year', 'color'])

Para obtener los valores del diccionario se puede usar el método ‘values()’

Code:

diccionario.values()

Output:

dict_values(['Ford', 'Mustang', 1964, 'white'])

Se puede usar una variable para apuntar a los valuess del diccionario, con lo que llamándola una vez es necesario

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se declara una vez la variable que apunta a los values

x = diccionario.values()

print(x)

# Se modifica un value

diccionario["year"] = 2020

# Se consulta la variable que apunta a los values

print(x)

Output:

dict_values(['Ford', 'Mustang', 1964])

dict_values(['Ford', 'Mustang', 2020])

Si lo que se quiere son los items enteros, es decir keys y values hay que usar el método items()

Code:

diccionario.items()

Output:

dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 2020)])

Se puede usar una variable para apuntar a los items del diccionario, con lo que llamándola una vez es necesario

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se declara una vez la variable que apunta a los items

x = diccionario.items()

print(x)

# Se modifica un value

diccionario["year"] = 2020

# Se consulta la variable que apunta a los items

print(x)

Output:

dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 1964)])

dict_items([('brand', 'Ford'), ('model', 'Mustang'), ('year', 2020)])

Se puede checkear si una key existe en el diccionario

Code:

"model" in diccionario

Output:

True

Se puede modificar un item accediendo a el directamente

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se modifica un item

diccionario["year"] = 2020

diccionario

Output:

{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}

O se puede modificar mediante el método update()

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se modifica un item

diccionario.update({"year": 2020})

diccionario

Output:

{'brand': 'Ford', 'model': 'Mustang', 'year': 2020}

Se puede añadir un item añadiéndolo sin más

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se modifica un item

diccionario["colour"] = "blue"

diccionario

Output:

{'brand': 'Ford', 'model': 'Mustang', 'year': 1964, 'colour': 'blue'}

O se puede añadir mediante el método update()

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se modifica un item

diccionario.update({"colour": "blue"})

diccionario

Output:

{'brand': 'Ford', 'model': 'Mustang', 'year': 1964, 'colour': 'blue'}

Se puede eliminar un item con una key específica mediante el método pop()

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se elimina un item

diccionario.pop("model")

diccionario

Output:

{'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 []

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se elimina un item

del diccionario["model"]

diccionario

Output:

{'brand': 'Ford', 'year': 1964}

Se elimina el diccionario entero si se usa del y no se especifica la key de un item

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se elimina un item

del diccionario

if 'diccionario' not in locals():

print("diccionario eliminado")

Output:

diccionario eliminado

Si lo que se quiere es eliminar el último item introducido se puede usar el método popitem()

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

# Se elimina el último item introducido

diccionario.popitem()

diccionario

Output:

{'brand': 'Ford', 'model': 'Mustang'}

Si se quiere limpiar el diccionario hay que usar el método clear()

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

diccionario.clear()

diccionario

Output:

{}

No se pueden copiar diccionarios mediante diccionario1 = diccionario2, ya que si se modifica diccionario1 también se modifica diccionario2

Code:

diccionario1 = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

diccionario2 = diccionario1

diccionario1["year"] = 2000

diccionario2["year"]

Output:

2000

Por lo que hay que usar el método copy()

Code:

diccionario1 = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

diccionario2 = diccionario1.copy()

diccionario1["year"] = 2000

diccionario2["year"]

Output:

1964

O hay que usar el constructor de diccionarios dict()

Code:

diccionario1 = {

"brand": "Ford",

"model": "Mustang",

"year": 1964

}

diccionario2 = dict(diccionario1)

diccionario1["year"] = 2000

diccionario2["year"]

Output:

1964

Los diccionarios pueden tener itemss de cualquier tipo de dato, incluso otros diccionarios. A este tipo de diccionarios se les denomina diccionarios nested

Code:

diccionario_nested = {

"child1" : {

"name" : "Emil",

"year" : 2004

},

"child2" : {

"name" : "Tobias",

"year" : 2007

},

"child3" : {

"name" : "Linus",

"year" : 2011

}

}

diccionario_nested

Output:

{'child1': {'name': 'Emil', 'year': 2004},

'child2': {'name': 'Tobias', 'year': 2007},

'child3': {'name': 'Linus', 'year': 2011}}

Code:

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

Output:

{'child1': {'name': 'Emil', 'year': 2004},

'child2': {'name': 'Tobias', 'year': 2007},

'child3': {'name': 'Linus', 'year': 2011}}

Estos son los métodos que se pueden usar en los diccionarios

Igual que podíamos hacer lists comprehensions mediante la sintaxis

list_comprehension = [expression for item in iterable if condition == True]

Podemos hacer disctionarys comprehensions mediante la siguiente sintaxis

dictionary_comprehension = [key expresion: value expresion for item in iterable if condition == True]

Veamos un ejemplo

Code:

dictionary_comprehension = {x: x**2 for x in (2, 4, 6) if x > 2}

dictionary_comprehension

Output:

{4: 16, 6: 36}

Los setss se utilizan en python para guardar un conjunto de items en una sola variable. Se puede guardar items de distinto tipo. Son no ordenados y no tienen indice.

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_

Code:

set_ = {'item0', 1, 5.3, "item4", 5, 6.6}

set_

Output:

{1, 5, 5.3, 6.6, 'item0', 'item4'}

No puede haber items duplicados, si encuentra algún item duplicado se queda solo con uno

Code:

set_ = {'item0', 1, 5.3, "item4", 5, 6.6, 'item0'}

set_

Output:

{1, 5, 5.3, 6.6, 'item0', 'item4'}

Se puede obtener la longitud del set mediante la función len()

Code:

len(set_)

Output:

6

Como se puede ver la longitud del set es 6 y no 7, ya que se queda con un solo 'item0'

Se puede checkear si un item se encuentra en el set

Code:

'item4' in set_

Output:

True

Se puede añadir un item al set mediante el método add()

Code:

set_.add(8.8)

set_

Output:

{1, 5, 5.3, 6.6, 8.8, 'item0', 'item4'}

Se puede añadir otro set mediante el método update()

Code:

set2 = {"item5", "item6", 7}

set_.update(set2)

set_

Output:

{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

Code:

lista = ["item9", 10, 11.2]

set_.update(lista)

set_

Output:

{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6', 'item9'}

Se puede eliminar un item determinado mediante el método remove()

Code:

set_.remove('item9')

set_

Output:

{1, 10, 11.2, 5, 5.3, 6.6, 7, 8.8, 'item0', 'item4', 'item5', 'item6'}

O mediante el método discard()

Code:

set_.discard('item6')

set_

Output:

{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 sets no son ordenados no hay manera de saber cúal es el último item. El método pop() devuelve el item eliminado

Code:

print(f"set antes de pop(): {set_}")

eliminado = set_.pop()

print(f"Se ha eliminado {eliminado}")

Output:

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 set

Code:

set_.clear()

set_

Output:

set()

Por úlitmo, con del se puede eliminar el set

Code:

del set_

if 'set_' not in locals():

print("set eliminado")

Output:

set eliminado

Una forma de unir sets es mediante el método union()

Code:

set1 = {"a", "b" , "c"}

set2 = {1, 2, 3}

set3 = set1.union(set2)

set3

Output:

{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

Code:

set1 = {"a", "b" , "c"}

set2 = {1, 2, 3}

set1.update(set2)

set1

Output:

{1, 2, 3, 'a', 'b', 'c'}

Estos métodos de union elimina los duplicados, pero si queremos obtener los items duplicados en dos sets usamos el método intersection()

Code:

set1 = {"apple", "banana", "cherry"}

set2 = {"google", "microsoft", "apple"}

set3 = set1.intersection(set2)

set3

Output:

{'apple'}

Si queremos obtener los items duplicados en dos sets, pero sin crear un set nuevo, usamos el método intersection_update()

Code:

set1 = {"apple", "banana", "cherry"}

set2 = {"google", "microsoft", "apple"}

set1.intersection_update(set2)

set1

Output:

{'apple'}

Ahora al revés, si queremos quedarnos con los no duplicados usamos el método symmetric_difference().

La diferencia entre eso y la unión entre dos sets es que en la unión se queda con todos los items, pero los que están duplicados solo los coge una vez. Ahora nos quedamos con los que no están duplicados

Code:

set1 = {"apple", "banana", "cherry"}

set2 = {"google", "microsoft", "apple"}

set3 = set1.symmetric_difference(set2)

set3

Output:

{'banana', 'cherry', 'google', 'microsoft'}

Si queremos quedarnos con los no duplicados sin crear un set nuevo usamos el método symmetric_difference_update()

Code:

set1 = {"apple", "banana", "cherry"}

set2 = {"google", "microsoft", "apple"}

set1.symmetric_difference_update(set2)

set1

Output:

{'banana', 'cherry', 'google', 'microsoft'}

Estos son los métodos que se pueden usar en los sets

Los frozensets son como los sets pero con la salvedad de que son inmutables, al igual que las tuplas son como las lists pero inmutables. Por lo que no podremos añadir o eliminar items

Hay solo dos booleanos en Python: True y False

Mediante la función bool() se puede evaluar si cualquier cosa es True o False

Code:

print(bool("Hello"))

print(bool(15))

print(bool(0))

Output:

True

True

False

Los siguientes datos son True:

  • Cualquier string que no esté vacío
  • Cualquier número escepto el 0
  • Cualquier lista, tupla, diccionario o set que no esté vacío

Code:

print(bool("Hola"))

print(bool(""))

Output:

True

False

Code:

print(bool(3))

print(bool(0))

Output:

True

False

Code:

lista = [1, 2, 3]

print(bool(lista))

lista = []

print(bool(lista))

Output:

True

False

Code:

tupla = (1, 2, 3)

print(bool(tupla))

tupla = ()

print(bool(tupla))

Output:

True

False

Code:

diccionario = {

"brand": "Ford",

"model": "Mustang",

"year": 1964,

"colors": ["red", "white", "blue"]

}

print(bool(diccionario))

diccionario.clear()

print(bool(diccionario))

Output:

True

False

Code:

set_ = {'item0', 1, 5.3, "item4", 5, 6.6}

print(bool(set_))

set_.clear()

print(bool(set_))

Output:

True

False

El tipo bytes es una secuencia inmutable de bytes. Solo admiten caracteres ASCII. También se pueden representar los bytes mediante números enteros cuyo valores deben cumplir 0 <= x < 256

Para crear un tipo byte debemos introducir antes el caracter b

Code:

byte = b"MaximoFN"

byte

Output:

b'MaximoFN'

También se pueden crear mediante su contructor bytes()

Code:

byte = bytes(10)

byte

Output:

b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'

Code:

byte = bytes(range(10))

byte

Output:

b'\x00\x01\x02\x03\x04\x05\x06\x07\x08\t'

Se pueden concatenar bytes mediante el operador +

Code:

byte1 = b'DeepMax'

byte2 = b'FN'

byte3 = byte1 + byte2

byte3

Output:

b'DeepMaxFN'

O medainte la repetición con el operador *

Code:

byte1 = b'MaximoFN '

byte2 = byte1 * 3

byte2

Output:

b'MaximoFN MaximoFN MaximoFN '

Podemos comprobar si un caracter está dentro de la cadena

Code:

b'D' in byte1

Output:

False

Estos son los métodos que se pueden usar en los bytes

Los bytearrays son igual que los bytes solo que son mutables

Code:

byte_array = bytearray(b'MaximoFN')

byte_array

Output:

bytearray(b'MaximoFN')

Los objetos memoryview permiten que el código Python acceda a los datos internos de un objeto que admite el protocolo de búfer 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 aumenta la velocidad de ejecución.

Code:

byte_array = bytearray('XYZ', 'utf-8')

print(f'Antes de acceder a la memoria: {byte_array}')

mem_view = memoryview(byte_array)

mem_view[2]= 74

print(f'Después de acceder a la memoria: {byte_array}')

Output:

Antes de acceder a la memoria: bytearray(b'XYZ')

Después de acceder a la memoria: bytearray(b'XYJ')

Operador suma +

Code:

3 + 5

Output:

8

Oeprador resta -

Code:

3 - 5

Output:

-2

Operador multiplicación *

Code:

3 * 5

Output:

15

Operador división /

Code:

3 / 5

Output:

0.6

Operador módulo %. Devuelve el resto de una división

Code:

25 % 2

Output:

1

Operador exponente **

Code:

5 ** 2

Output:

25

Operador división entera //

Code:

25 // 2

Output:

12

Operador es igual ==

Code:

1 == 1

Output:

True

Operador es distinto !=

Code:

1 != 2

Output:

True

Operador es mayor que >

Code:

3 > 2

Output:

True

Operador es menor que <

Code:

2 < 3

Output:

True

Operador es mayor o igual que >=

Code:

3 >= 3

Output:

True

Operador es menor o igual que <=

Code:

3 <= 3

Output:

True

Operador and

Code:

True and True

Output:

True

Operador or

Code:

True or False

Output:

True

Operador not

Code:

not False

Output:

True

Operador is

Code:

5.3 is 5.3

Output:

True

Operador is not

Code:

5.3 is not 5

Output:

True

Operador in

Code:

x = ["apple", "banana"]

"banana" in x

Output:

True

Operador not in

Code:

x = ["apple", "banana"]

"orange" not in x

Output:

True

Operador AND &

Code:

a = 60 # 60 = 0011 1100

b = 13 # 13 = 0000 1101

c = a & b; # 12 = 0000 1100

c

Output:

12

Operador OR |

Code:

a = 60 # 60 = 0011 1100

b = 13 # 13 = 0000 1101

c = a | b; # 61 = 0011 1101

c

Output:

61

Operador XOR ^

Code:

a = 60 # 60 = 0011 1100

b = 13 # 13 = 0000 1101

c = a ^ b; # 49 = 0011 0001

c

Output:

49

Operador NOT ~

Code:

a = 60 # 60 = 0011 1100

c = ~a; # -61 = 1100 0011

c

Output:

-61

Operador desplazamiento hacia la izquierda <<

Code:

a = 60 # 60 = 0011 1100

c = a << 2; # 240 = 1111 0000

c

Output:

240

Operador desplazamiento hacia la derecha >>

Code:

a = 60 # 60 = 0011 1100

c = a >> 2; # 15 = 0000 1111

c

Output:

15

Operador =

Code:

a = 5

a

Output:

5

Operador +=. x += y es equivalente a x = x + y

Code:

a += 5

a

Output:

10

Operador -=. x -= y es equivalente a `x = x – y

Code:

a -= 5

a

Output:

5

Operador =. x = y es equivalente a `x = x * y

Code:

a *= 3

a

Output:

15

Operador /=. x /= y es equivalente a `x = x / y

Code:

a /= 3

a

Output:

5.0

Operador %=. x %= y es equivalente a `x = x % y

Code:

a = 25

a %= 2

a

Output:

1

Operador //=. x //= y es equivalente a `x = x // y

Code:

a = 25

a //= 2

a

Output:

12

Operador =. x = y es equivalente a `x = x ** y

Code:

a = 5

a **= 2

a

Output:

25

Operador &=. x &= y es equivalente a `x = x & y

Code:

a = 60 # 60 = 0011 1100

b = 13 # 13 = 0000 1101

a &= b; # 12 = 0000 1100

a

Output:

12

Operador |=. x |= y es equivalente a `x = x | y

Code:

a = 60 # 60 = 0011 1100

b = 13 # 13 = 0000 1101

a |= b; # 61 = 0011 1101

a

Output:

61

Operador ^=. x ^= y es equivalente a `x = x ^ y

Code:

a = 60 # 60 = 0011 1100

b = 13 # 13 = 0000 1101

a ^= b; # 49 = 0011 0001

a

Output:

49

Operador >>=. x >>= y es equivalente a `x = x >> y

Code:

a = 60 # 60 = 0011 1100

a <<= 2; # 240 = 1111 0000

a

Output:

240

Operador <<=. x <<= y es equivalente a `x = x << y

Code:

a = 60 # 60 = 0011 1100

a >>= 2; # 15 = 0000 1111

a

Output:

15

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ódgo 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

Mediante if podemos crear condiciones

Code:

if len('MaximoFN') == 8:

print('MaximoFN tiene 8 caracteres')

Output:

MaximoFN tiene 8 caracteres

Si queremos crear más de una condición podemos usar elif

Code:

if len('MaximoFN') < 8:

print('MaximoFN tiene menos de 8 caracteres')

elif len('MaximoFN') == 8:

print('MaximoFN tiene 8 caracteres')

Output:

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

Code:

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')

Output:

MaximoFN tiene 8 caracteres

Si queremos escribir todo en una sola línea

Code:

if len('MaximoFN') == 8: print('MaximoFN tiene 8 caracteres')

Output:

MaximoFN tiene 8 caracteres

Igual, si queremos escribir todo en una línea, pero con varias condiciones

Code:

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')

Output:

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

Code:

if len('MaximoFN') < 8:

print('MaximoFN tiene menos de 8 caracteres')

elif len('MaximoFN') > 8:

pass

else:

print('MaximoFN tiene 8 caracteres')

Output:

MaximoFN tiene 8 caracteres

El bucle while se ejecuta mientras la condición sea True

Code:

i = 0

string = 'MaximoFN'

while len(string) > i:

print(string[i], end='')

i += 1

Output:

MaximoFN

Si queremos que el bucle pare por alguna condición usamos break

Code:

i = 0

string = 'MaximoFN'

while len(string) > i:

if string[i] == 'F':

break

print(string[i], end='')

i += 1

Output:

Maximo

Si queremos que una de las iteracciones no se ejecute por alguna razón usamos continue

Code:

i = 0

string = 'Maximo FN'

while len(string) > i:

if string[i] == ' ':

i += 1

continue

print(string[i], end='')

i += 1

Output:

MaximoFN

Mediante else se puede ejecutar un bloque de código si la condición del while no es True

Code:

i = 0

string = 'MaximoFN'

while len(string) > i:

print(string[i], end='')

i += 1

else:

print("\nSe ha terminado el while")

Output:

MaximoFN

Se ha terminado el while

El bucle for se usa para ejecutar código mientras se itera por una secuencia, esta secuencia puede ser un cualquir elemento iterable de Python (string, lista, tupla, range, diccionario, set)

Code:

string = 'MaximoFN'

for x in string:

print(x, end='')

Output:

MaximoFN

Code:

lista = ['M', 'a', 'x', 'i', 'm', 'o', 'F', 'N']

for x in lista:

print(x, end='')

Output:

MaximoFN

Code:

tupla = ('M', 'a', 'x', 'i', 'm', 'o', 'F', 'N')

for x in tupla:

print(x, end='')

Output:

MaximoFN

Code:

string = 'MaximoFN'

for i in range(len(string)):

print(string[i], end='')

Output:

MaximoFN

Code:

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='')

Output:

MaximoFN

También se puede iterar por los sets, pero como son elementos no ordenados, no tendremos control del orden de ejecución

Code:

set_ = {'M', 'a', 'x', 'i', 'm', 'o', 'F', 'N'}

for x in set_:

print(x, end='')

Output:

NximoaMF

Si queremos que el bucle pare por alguna condición usamos break

Code:

string = 'MaximoFN'

for x in string:

if x == 'F':

break

print(x, end='')

Output:

Maximo

Si queremos que una de las iteracciones no se ejecute por alguna razón usamos continue

Code:

string = 'Maximo FN'

for x in string:

if x == ' ':

continue

print(x, end='')

Output:

MaximoFN

Mediante else se puede ejecutar un bloque de código si la condición del while no es True

Code:

string = 'MaximoFN'

for x in string:

print(x, end='')

else:

print("\nSe ha terminado el for")

Output:

MaximoFN

Se ha terminado el for

Si por ejemplo queremos hacer la estructura del for pero no queremos, de momento, codificar el interior podemos usar pass

Code:

string = 'MaximoFN'

for x in string:

pass

print('Interior del for no codificado')

Output:

Interior del for no codificado

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

Code:

def funcion():

print('MaximoFN')

Para llamar a la función solo es necesario escribir su nombre

Code:

funcion()

Output:

MaximoFN

A las funciones se le pueden pasar todos los argumentos que se quiera, dentro de los paréntesis y separados por comas

Code:

def funcion(string1, string2):

print(string1 + ' ' + string2)

funcion("Hola", "MaximoFN")

Output:

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 obtendremos 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

Code:

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")

Output:

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 indicando su nombre

Code:

def funcion(argumento1, argumento2, argumento3):

print(argumento1 + ' '+ argumento2 + ' ' + argumento3)

funcion(argumento3 = "MaximoFN", argumento1 = "Blog", argumento2 = "de")

Output:

Blog de MaximoFN

En caso de querer pasar los argumentos con su nombre, pero en caso de no saber cuantos argumentos se van a pasar se puede usar **kargs. En este caso se le pasará un diccionario con los argumentos

Code:

def funcion(**kargumentos):

print("Autor del blog: " + kargumentos["autor"])

funcion(blog = "Blog", pertenencia = "de", autor = "MaximoFN")

Output:

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

Code:

def funcion(argumento1, argumento2, argumento3 = "MaximoFN"):

print(argumento1 + ' '+ argumento2 + ' ' + argumento3)

funcion("Blog", "de")

Output:

Blog de MaximoFN

Se puede pasar cualquier tipo de dato como argumento, por ejemplo si se pasa un lista como argumento, dentro de la función, dicho argumento será tratado como una lista

Code:

def funcion(argumento):

longitud_lista = len(argumento)

for i in range(longitud_lista):

print(argumento[i], end=' ')

funcion(["Blog", "de", "MaximoFN"])

Output:

Blog de MaximoFN

Las funciones pueden devolver datos, esto se hace mediante la palabra reservada return

Code:

def funcion(argumento):

longitud_lista = len(argumento)

string = ""

for i in range(longitud_lista):

string = string + argumento[i] + ' '

return string

print(funcion(["Blog", "de", "MaximoFN"]))

Output:

Blog de MaximoFN

Pueden devolver más de un dato

Code:

def funcion(argumento):

longitud_lista = len(argumento)

string0 = argumento[0]

string1 = argumento[1]

string2 = argumento[2]

return string0, string1, string2

dato0, dato1, dato2 = funcion(["Blog", "de", "MaximoFN"])

print(dato0 + ' ' + dato1 + ' ' + dato2)

Output:

Blog de MaximoFN

Si uno de los datos devueltos no nos interesa podemos pasar de el mediante _

Code:

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)

Output:

MaximoFN

Si por ejemplo queremos hacer la estructura de la función pero no queremos, de momento, codificar el interior podemos usar pass

Code:

def funcion():

pass

funcion()

Una función puede llamarse a si 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

Code:

def factorial(n):

if n == 0 or n == 1:

return 1

else:

return n * factorial(n-1)

factorial(5)

Output:

120

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

Code:

abs(-5)

Output:

5

A continuación se muestra una lista de estas funciones

Code:

import builtins

dir(builtins)

Output:

['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']

Se puede añadir una explicación de una fucnió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.

Code:

def funcion():

"Esta es la explicación de la función"

None

help(funcion)

Output:

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

Code:

funcion.__doc__

Output:

'Esta es la explicación de la función'

Los decoradores son una funcionalidad de Python que premiten añadir características nuevas a una función

Se crea una función decorador que tiene como parámetro otra función. Entonces la función decorador añade la característica nueva a la función que recibe

Code:

def decorador(parametro_funcion):

"""Agrega barritas arriba y abajo de la funcion"""

def envoltorio():

"""Aplica las barritas al texto"""

print("==================")

parametro_funcion()

print("==================")

return envoltorio

def funcion():

print("MaximoFN")

funcion_envoltorio = decorador(funcion)

print('Función sin decoradores: ')

funcion()

print('\nFunción con decoradores: ')

funcion_envoltorio()

Output:

Función sin decoradores:

MaximoFN

Funció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

Code:

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

@decorador2

def funcion2():

print("MaximoFN")

print('Función con decoradores: ')

funcion2()

Output:

Función con decoradores:

==================

MaximoFN

==================

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í

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.

Code:

def saludo(saludo, *nombres):

for nombre in nombres:

print(f"{saludo}, {nombre}")

saludo("Hola", "Alicia", "Roberto", "Carlos")

Output:

Hola, Alicia

Hola, Roberto

Hola, Carlos

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.

Code:

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)

Output:

Hola Juan, tu edad es 22 años

Hola Maria, tu edad es 32 años

Hola Pedro, tu edad es 25 años

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

Code:

x = lambda a : a + 10

print(x(5))

Output:

15

Code:

x = lambda a, b, c : a + b + c

print(x(5, 6, 2))

Output:

13

El poder de lambda se muestra mejor cuando los usa como una función anónima dentro de otra función.

Code:

def myfunc(n):

return lambda a : a * n

mydoubler = myfunc(2)

mytripler = myfunc(3)

print(f"mydoubler: {mydoubler(11)}")

print(f"mytripler: {mytripler(11)}")

Output:

mydoubler: 22

mytripler: 33

La función map permite aplicar a cada elemento de una estructura iterable una función

Code:

lista = [1, 2, 3]

def funcion_mas_1(valor):

return valor + 1

lista_modificada = list(map(funcion_mas_1, lista))

lista_modificada

Output:

[2, 3, 4]

Esto es equivalente a usar list comprehension

Code:

lista_modificada = [funcion_mas_1(x) for x in lista]

lista_modificada

Output:

[2, 3, 4]

La función filter permite seleccionar los elementos de una estructura iterable que cumplan con una característica

Code:

lista = [1, 2, 3, 4, 5, 6, 7]

def esPar(valor):

return valor % 2 == 0

lista_filtrada = list(filter(esPar, lista))

lista_filtrada

Output:

[2, 4, 6]

Esto es equivalente a usar list comprehension

Code:

lista_filtrada = [x for x in lista if esPar(x)]

lista_filtrada

Output:

[2, 4, 6]

La función reduce permite realizar tareas acumulativas en estructuras iterables

Code:

from functools import reduce

lista = [1, 22, 33]

def acumular(valor, acumulador):

print(f'valor = {valor}, acumulador = {acumulador}, acumulacion = {valor + acumulador}')

return valor + acumulador

acumulacion = reduce(acumular, lista)

print(f'\nacumulacion = {acumulacion}')

Output:

valor = 1, acumulador = 22, acumulacion = 23

valor = 23, acumulador = 33, acumulacion = 56

acumulacion = 56

Con la función zip se puede comprimir varias estructuras iterables en una sola, es decir permite agrupar varias estructuras Ax en una sola estructura B. La estructura B está formada por tuplas de los elementos de las estructuras Ax

Code:

nombres = ["Manolo", "Andres", "Fernando"]

altura = [181, 178, 180]

my_zip = list(zip(nombres, altura))

my_zip

Output:

[('Manolo', 181), ('Andres', 178), ('Fernando', 180)]

Supongamos que queremos iterar sobre una secuencia de números, pero de una manera especial que no nos ofrece ningún tipo de bucle, pues 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

Code:

def iterador_custom(N):

for i in range (N):

if i % 3 == 0:

yield i

generador = iterador_custom(20)

for i in generador:

print(i)

Output:

0

3

6

9

12

15

18

Acabamos de hacer un iterador por números múltiplos de 3

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

Code:

def increment(x):

return x + 1

def hof(f, x):

return 2*f(x)

print(hof(increment, 3))

Output:

8

Python es un lenguaje de programación orientado a objetos. Casi todo en Python es un objeto, con sus propiedades 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

Code:

class Clase:

variable = 'MaximoFN'

Una vez creada la clase se puede crear un objeto de dicha clase

Code:

objeto = Clase()

Clase.variable

Output:

'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

Con esta función se suelen inicializar las variables de las clases, o se ejecuta el código que se necesite cuando se crea un objeto de la clase

Code:

class Persona:

def __init__(self, nombre, edad):

self.nombre = nombre

self.edad = edad

objeto_persona = Persona("Miguel", 36)

print(objeto_persona.nombre)

print(objeto_persona.edad)

Output:

Miguel

36

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

Code:

class Persona:

def __init__(self, nombre, edad):

self.nombre = nombre

self.edad = edad

def saludar(self):

print(f'Hola mi nombre es {self.nombre} y tengo {self.edad} años')

objeto_persona = Persona("Miguel", 36)

objeto_persona.saludar()

Output:

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

Code:

class Persona:

def __init__(yo_mismo, nombre, edad):

yo_mismo.nombre = nombre

yo_mismo.edad = edad

def 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()

Output:

Hola mi nombre es Miguel y tengo 36 años

Se pueden modificar las variables de los objetos

Code:

objeto_persona.nombre = 'Marta'

objeto_persona.saludar()

Output:

Hola mi nombre es Marta y tengo 36 años

Incluso eliminarlas

Code:

del objeto_persona.nombre

También se puede eliminar el objeto entero

Code:

del objeto_persona

Si por ejemplo queremos hacer la estructura de la clase pero no queremos, de momento, codificar el interior podemos usar pass

Code:

class Persona:

pass

objeto_persona = Persona()

La herencia nos permite definir una clase que hereda 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

Code:

class Persona:

def __init__(self, nombre, apellido):

self.nombre = nombre

self.apellido = apellido

def imprimir_nombre(self):

print(f'Me llamo {self.nombre} {self.apellido}')

objeto_padre = Persona("Laura", "Perez")

objeto_padre.imprimir_nombre()

Output:

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

Code:

class Estudiante(Persona):

pass

Y a la hora de crear el objeto de la clase hija, se le pasan los parámetros que la clase padre necesita

Code:

objeto_hijo = Estudiante("Mariano", "Sanz")

objeto_hijo.imprimir_nombre()

Output:

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 duder 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

Code:

class Estudiante(Persona):

def __init__(self, nombre, apellido):

Persona.__init__(self, nombre, apellido)

objeto_hijo = Estudiante("Mariano", "Sanz")

objeto_hijo.imprimir_nombre()

Output:

Me llamo Mariano Sanz

Otra forma es mediante super(), en este caso no hace falta pasarle la variable self

Code:

class Estudiante(Persona):

def __init__(self, nombre, apellido):

super().__init__(nombre, apellido)

objeto_hijo = Estudiante("Mariano", "Sanz")

objeto_hijo.imprimir_nombre()

Output:

Me llamo Mariano Sanz

Al modificar las funciones se puede añadir código nuevo

Code:

class Estudiante(Persona):

def __init__(self, nombre, apellido, curso):

Persona.__init__(self, nombre, apellido)

self.curso = curso

def 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()

Output:

Me llamo Mariano Sanz

Estoy en el curso número 4

Por último se pueden añadir nuevos métodos

Code:

class Estudiante(Persona):

def __init__(self, nombre, apellido, curso):

Persona.__init__(self, nombre, apellido)

self.curso = curso

def 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()

Output:

Me llamo Mariano Sanz

Estoy en el curso número 4

Soy un estudiante del curso número 4

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

Code:

class Vector:

def __init__(self, x, y):

self.x = x

self.y = y

def __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)

Output:

Vector (4, 6)

Vector (3, 8)

Todas las posibles sobre carga de operaciones 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ón divmod().

__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ón abs().
  • __invert__(self): sobrecarga el operador de inversión (~).
  • __complex__(self): sobrecarga la función complex().
  • __int__(self): sobrecarga la función int().
  • __float__(self): sobrecarga la función float().

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 nuestro propia clase iterable, siempre que tenga las funciones __len__ y __getitem__

Code:

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)) # 10

print(iterator[0]) # 0

print(iterator[1]) # 1

Output:

10

0

1

Ahora podemo iterar con el objeto de nuestra clase con bucles for por ejemplo

Code:

for i in iterator:

print(i, end=" ") # 0 1 2 3 4 5 6 7 8 9

Output:

0 1 2 3 4 5 6 7 8 9

Nos puede interesar llamar a un objeto de una función como una clase, esto se puede conseguir añadiendo la función __call__ a la clase

Code:

class potencia:

def __init__(self, base):

self.base = base

def __call__(self, potencia):

return self.base ** potencia

potencia_cuadrado = potencia(2)

print(potencia_cuadrado(3)) # 8

Output:

8

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 qye añadir __ antres del atributo a clase

Code:

class Privados:

def __init__(self):

self.publico = "Soy público"

self.__privado = "Soy privado"

def getPrivado(self):

return self.__privado

def setPrivado(self, valor):

self.__privado = valor

def __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")

Output:

Acceso al atributo publico: Soy público

Acceso al atributo privado: No se puede acceder al atributo privado

Acceso al atributo privado mediante el accesor: Soy privado

Llamada a la función privada: No se puede llamar a la función privada

Llamada a la función pública: Soy una función privada

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 atravesar todos los valores.

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 puede obtener un iterador.

Todos estos objetos tienen un método iter() que se usa para obtener un iterador:

Code:

tupla = ("manzana", "plátano", "cereza")

iterable = iter(tupla)

print(next(iterable))

print(next(iterable))

print(next(iterable))

Output:

manzana

plátano

cereza

Code:

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=' ')

Output:

p l á t a n o

El bucle for en realidad crea un objeto iterador y ejecuta el método next() para cada bucle.

Code:

tupla = ("manzana", "plátano", "cereza")

for x in tupla:

print(x)

Output:

manzana

plátano

cereza

Code:

string = "plátano"

for x in string:

print(x, end=' ')

Output:

p l á t a n o

Para crear un objeto/clase como iterador, hay que implementar los métodos __iter__() y __next__().

Code:

class Numeros:

def __iter__(self):

self.a = 1

return self

def __next__(self):

x = self.a

self.a += 1

return x

objeto_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=' ')

Output:

1 2 3 4 5

El ejemplo anterior continuaría para siempre si tuviera suficientes llámadas 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:

Code:

class Numeros:

def __iter__(self):

self.a = 1

return self

def __next__(self):

if self.a <= 20:

x = self.a

self.a += 1

return x

else:

raise StopIteration

objeto_iterador = Numeros()

iterador = iter(objeto_iterador)

for x in iterador:

print(x, end=' ')

Output:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20

Podemos iterar por un objeto iterable obteniendo en cada iteracción su indice y su valor mediante el método enumerate()

Code:

string = "MaximoFN"

for index, valor in enumerate(string):

print(f"En la posición {index}, está el caracter {valor}")

Output:

En la posición 0, está el caracter M

En la posición 1, está el caracter a

En la posición 2, está el caracter x

En la posición 3, está el caracter i

En la posición 4, está el caracter m

En la posición 5, está el caracter o

En la posición 6, está el caracter F

En la posición 7, está el caracter N

Si tenemos dos objetos iterables, cuya longitud sea la misma, podemos iterar por los dos a la vez mediante el método zip()

Code:

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}")

Output:

En el primer string hay M, en el segundo string hay P

En el primer string hay a, en el segundo string hay y

En el primer string hay x, en el segundo string hay t

En el primer string hay i, en el segundo string hay h

En el primer string hay m, en el segundo string hay o

En el primer string hay o, en el segundo string hay n

En el primer string hay F, en el segundo string hay P

En el primer string hay N, en el segundo string hay o

En el primer string hay _, en el segundo string hay s

En el primer string hay _, en el segundo string hay t

Una variable solo está disponible dentro de la región en la que se crea. A esto se le llama alcance

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.

Code:

def funcion():

x = 300

print(x)

funcion()

Output:

300

La variable x no está disponible fuera de la función, pero está disponible para cualquier función dentro de la función

Code:

def funcion():

x = 300

def funcion_interna():

print(x)

funcion_interna()

funcion()

Output:

300

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.

Code:

x = 300

def funcion():

print(f'Ámbito local: {x}')

funcion()

print(f'Ámbito global: {x}')

Output:

Á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

Code:

x = 300

def funcion():

x = 200

print(f'Variable local: {x}')

funcion()

print(f'Variable global: {x}')

Output:

Variable local: 200

Variable 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.

Code:

def funcion():

global x

x = 300

funcion()

print(f'Variable global: {x}')

Output:

Variable global: 300

Además, el uso de la palabra clave global realizar un cambio en una variable global dentro de una función.

Code:

x = 300

def funcion():

global x

x = 200

funcion()

print(f'Variable global: {x}')

Output:

Variable global: 200

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 linea) si escribimos el caracter ! antes de un comando podremos ejecutar comandos de consola

Primero vamos a ver en qué directorio estamos, para eso usamos el comando pwd (print working directory)

Code:

!pwd

Output:

/home/wallabot/Documentos/web/portafolio/posts

Vamos a crear una carpeta para crear nuestros módulos con el comando mkdir (make directory)

Code:

!mkdir introduccion_python

A continuación veamos qué archivos hay es nuestra carpeta. Esto lo haremos mediante el comando ls (list)

Code:

!ls introduccion_python

Vemos que está vacía, creamos un nuevo archivo .py en el que vamos a crear nuestro módulo

Code:

%%writefile introduccion_python/modulo1.py

def funcion_del_modulo(nombre):

print("Hola, " + nombre)

Output:

Writing introduccion_python/modulo1.py

Volvemos a ver qué archivos hay en nuestra carpeta

Code:

!ls introduccion_python

Output:

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

Code:

import introduccion_python.modulo1

introduccion_python.modulo1.funcion_del_modulo('MaximoFN')

Output:

Hola, MaximoFN

Si queremos que dentro de nuestro código, el módulo tenga un nombre determinado podemos usar la palabra as

Code:

import introduccion_python.modulo1 as mod1

mod1.funcion_del_modulo('MaximoFN')

Output:

Hola, MaximoFN

Si el módulo tiene varias funciones, pero solo queremos importar una podemos mediante el uso de las palabras from e import. La forma sería

from import

En este caso no hace falta indicar el nombre del módulo al llamar a la función

Code:

%%writefile introduccion_python/modulo2.py

def 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")

Output:

Writing introduccion_python/modulo2.py

Code:

from introduccion_python.modulo2 import funcion2_del_modulo

funcion2_del_modulo('MaximoFN')

Output:

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

Code:

import platform

x = platform.system()

x

Output:

'Linux'

Vamos ahora a crear un archivo llamado modulo3.py

Code:

%%writefile introduccion_python/modulo3.py

print("Hola desde modulo3")

def funcion_del_modulo():

return "Hola desde la función del modulo3"

Output:

Overwriting introduccion_python/modulo3.py

Si ahora importamos modulo3.py para usar la función funcion_del_modulo veamos qué ocurre

Code:

import introduccion_python.modulo3 as mod3

print(mod3.funcion_del_modulo())

Output:

Hola desde modulo3

Hola 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 scrip?

Code:

!python introduccion_python/modulo3.py

Output:

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

Code:

%%writefile introduccion_python/modulo3.py

print("Hola desde modulo3")

def funcion_del_modulo():

return "Hola desde la función del modulo3"

if __name__ == "__main__":

funcion_del_modulo()

Output:

Overwriting introduccion_python/modulo3.py

Si ahora llamo a main.py desde otro módulo, ya no se ejecutará el print

Code:

import introduccion_python.modulo3 as mod3

print(mod3.funcion_del_modulo())

Output:

Hola desde la función del modulo3

Y si lo ejecuto como un script independiente, se ejecutará la función funcion_del_modulo

Code:

!python introduccion_python/modulo3.py

Output:

Hola desde modulo3

En python podemos crearnos nuestros propios paquetes, para ello creamos una carpeta con el nombre del paquete

Code:

!mkdir mi_paquete_de_python

Creamos ahora dos archivos dentro

Code:

!touch mi_paquete_de_python/modulo1.py mi_paquete_de_python/modulo2.py

Y escribimos en ellos

Code:

%%writefile mi_paquete_de_python/modulo1.py

def 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")

Output:

Overwriting mi_paquete_de_python/modulo1.py

Code:

%%writefile mi_paquete_de_python/modulo2.py

def 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")

Output:

Overwriting mi_paquete_de_python/modulo2.py

Ahora podemos llamar a las funciones de nuestro paquete

Code:

from mi_paquete_de_python import modulo1 as mod1

from mi_paquete_de_python import modulo2 as mod2

mod1.funcion1()

mod1.funcion2()

mod2.funcion1()

mod2.funcion2()

Output:

Hola desde la función 1 del módulo 1

Hola desde la función 2 del módulo 1

Hola desde la función 1 del módulo 2

Hola 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

Code:

!touch mi_paquete_de_python/__init__.py

Code:

%%writefile mi_paquete_de_python/__init__.py

import modulo1

import modulo2

Output:

Overwriting mi_paquete_de_python/__init__.py

Ahora podemos solamente importar nuestro paquete, que ya internamente se han importado todos los módulos

Code:

import mi_paquete_de_python as mi_paquete

mi_paquete.modulo1.funcion1()

mi_paquete.modulo1.funcion2()

mi_paquete.modulo2.funcion1()

mi_paquete.modulo2.funcion2()

Output:

Hola desde la función 1 del módulo 1

Hola desde la función 2 del módulo 1

Hola desde la función 1 del módulo 2

Hola desde la función 2 del módulo 2

De esta manera solo tenemos que hacer un import

Cuando ocurre un error, o una excepción como se llama realmente, Python normalmente se detendrá y generará un mensaje de error.

Estas excepciones se pueden manejar usando las declaraciones try y except

Code:

try:

print(variable_no_declarada)

except:

print("Ha ocurrido una excepción")

Output:

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

Code:

try:

print(variable_no_declarada)

except NameError:

print("La variable \'variable_no_declarada\' no está definida")

except:

print("Algo inesperado ha ocurrido")

Output:

La variable 'variable_no_declarada' no está definida

Se puede usar la palabra else para indicar el caso en el que no haya ocurrido un error

Code:

try:

print('MaximoFN')

except NameError:

print("Ha ocurrido una excepción")

else:

print('Todo OK')

Output:

MaximoFN

Todo OK

con la palabra finally se ejecutará un codigo al final haya ocurrido una excepción o no

Code:

try:

print(variable_no_declarada)

except:

print("Ha ocurrido una excepción")

finally:

print("'try except' finallizado")

Output:

Ha ocurrido una excepción

'try except' finallizado

Esto puede resultar útil para cerrar objetos y limpiar recursos

Code:

class Clase:

variable = 'MaximoFN'

objeto = Clase()

try:

print(Clase.mi_variable)

except:

print("Ha ocurrido una excepción")

finally:

del objeto

Output:

Ha ocurrido una excepción

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

Code:

def division(numerador, denominador):

if denominador == 0:

raise Exception("El denominador no puede ser 0")

return numerador/denominador

print(division(10, 0))

Output:

---------------------------------------------------------------------------

Exception Traceback (most recent call last)

<ipython-input-16-33fb6066fa78> in <module>

5 return numerador/denominador

6

----> 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")

4

5 return numerador/denominador

Exception: El denominador no puede ser 0

Se puede definir qué tipo de error generar y el texto que se imprimirá al usuario

Code:

def division(numerador, denominador):

if denominador == 0:

raise TypeError("El denominador no puede ser 0")

return numerador/denominador

print(division(10, 0))

Output:

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

<ipython-input-17-26bfa63ae44c> in <module>

5 return numerador/denominador

6

----> 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")

4

5 return numerador/denominador

TypeError: El denominador no puede ser 0

Durante este post en varias ocasiones han aparecido palabras reservadas de Python o keywords, estas son una serie de palabras reservadas por Python

A continuación se muestra una lista de las keywords

Code:

import keyword

keyword.kwlist

Output:

['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']

Importando el módulo this podemos leer el zen de Python, es decir, su filosofía o principios

Code:

import this

Output:

The Zen of Python, by Tim Peters

Beautiful 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!

Continúa leyendo

  • DoLa – Decoding by Contrasting Layers Improves Factuality in Large Language Models
    ¿Alguna vez has hablado con un LLM y te ha respondido algo que suena como si hubiera estado bebiendo café de máquina durante toda la noche? 😂 ¡Eso es lo que llamamos una «alucinación» en el mundo de los LLMs! Pero no te preocupes, porque no es que tu modelo de lenguaje esté loco (aunque a veces puede parecerlo 🤪). La verdad es que los LLMs pueden ser un poco… creativos cuando se trata de generar texto. Pero gracias a DoLa, un método que utiliza capas de contraste para mejorar la factibilidad de los LLMs, podemos evitar que nuestros modelos de lenguaje se conviertan en escritores de ciencia ficción 😂. En este post, te explicaré cómo funciona DoLa y te mostraré un ejemplo de código para que puedas entender mejor cómo hacer que tus LLMs sean más fiables y menos propensos a inventar historias. ¡Vamos a salvar a nuestros LLMs de la locura y hacer que sean más útiles! 🚀
  • QLoRA: Efficient Finetuning of Quantized LLMs
    ¡Hola a todos! 🤗 Hoy vamos a hablar de QLoRA, la técnica que te permitirá hacer que tus modelos de lenguaje sean más eficientes y rápidos ⏱️. Pero, ¿cómo lo hace? 🤔 Bueno, primero utiliza la cuantización para reducir el tamaño de los pesos del modelo, lo que ahorra memoria y velocidad 📈. Luego, aplica LoRA (Low-Rank Adaptation), que es como un superpoder que permite al modelo adaptarse a nuevos datos sin necesidad de volver a entrenar desde cero 💪. Y, para que veas cómo funciona en la práctica, te dejo un ejemplo de código que te hará decir ‘¡Eureka!’ 🎉. ¡Vamos a sumergirnos en el mundo de QLoRA y descubrir cómo podemos hacer que nuestros modelos sean más inteligentes y eficientes! 🤓
  • GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers
    ¡Atención, desarrolladores! 🚨 ¿Tienes un modelo de lenguaje que es demasiado grande y pesado para tu aplicación? 🤯 ¡No te preocupes, GPTQ está aquí para ayudarte! 🤖 Este algoritmo de cuantización es como un mago que hace desaparecer los bits y bytes innecesarios, reduciendo el tamaño de tu modelo sin perder demasiada precisión. 🎩 Es como comprimir un archivo sin perder calidad. ¡Es una forma de hacer que tus modelos sean más eficientes y rápidos! 🚀
  • llm.int8() – 8-bit Matrix Multiplication for Transformers at Scale
    ¡Prepárate para ahorrar espacio y acelerar tus modelos! 💥 En este post, voy a explorar el método llm.int8(), una técnica de cuantización que te permite reducir el tamaño de tus modelos de aprendizaje automático sin sacrificar demasiada precisión. 📊 ¡Eso significa que podrás entrenar y desplegar modelos más grandes y complejos en menos espacio y con menor consumo de recursos! 💻 Vamos a ver cómo utilizar llm.int8() con transformers para cuantizar un modelo y hacer que sea más eficiente, sin perder la esencia de su inteligencia artificial. 🤖
  • LLMs quantization
    ¡Imagina que tienes un modelo de lenguaje gigante que puede responder a cualquier pregunta, desde la capital de Francia hasta la receta perfecta para hacer brownies! 🍞️🇫🇷 Pero, ¿qué pasa cuando ese modelo tiene que caber en un dispositivo móvil? 📱 ¡Eso es donde entra en juego la cuantización! 🎉 Esta técnica nos permite reducir el tamaño de los modelos sin sacrificar su precisión, lo que significa que podemos disfrutar de inteligencia artificial en nuestros dispositivos móviles sin necesidad de un supercomputador. 💻 ¡Es como comprimir un elefante en una caja de zapatos, pero sin aplastar al elefante! 🐘😂
Resumen
Introducción a Python
Nombre del artículo
Introducción a Python
Descripción
Python 🐍 es uno de los lenguajes de programación 💻 MÁS USADO. Entra y aprende todo lo que necesitas sobre Python 🐍
MaximoFN
MaximoFN
MaximoFN