Python
Realizado por Daniel Bazo Correa.
Bibliografía
1. Utilidades
1.1. Línea de comandos
Los comandos de terminal son herramientas poderosas que pueden variar según el sistema operativo. Aquí se presentan algunos comandos útiles:
Comando | Función |
---|---|
| Muestra el directorio actual |
| Lista todos los archivos y carpetas en el directorio actual |
| Cambia al directorio especificado |
| Limpia el terminal |
| Navega al directorio Home del sistema (Carpeta Usuario y Carpeta de acceso compartido) |
| Abre un cuaderno Jupyter en Visual Studio Code |
| Muestra la documentación de una función, método, etc. dentro de Jupyter |
Si estás utilizando Anaconda en Linux, estos comandos pueden ser útiles:
Comando | Función |
---|---|
| Abre el navegador de Anaconda desde el terminal de Linux |
| Si el navegador de Anaconda tiene problemas para abrir el cuaderno Jupyter, puedes abrirlo directamente sin usar Anaconda |
2. Objetos y estructura de datos básica
2.1. Tipos de datos fundamentales
Python ofrece una variedad de tipos de datos fundamentales que se utilizan para definir y manipular información en el código. Aquí hay una lista de los tipos de datos más comunes:
Tipo de datos | Palabra reservada | Ejemplos |
---|---|---|
Números enteros |
| 3, 300, 200 |
Números con coma flotante |
| 2.3, 4.6, 100.0 |
Cadenas de texto |
| "Hola", "Hola muy buenas", "2000" |
Listas |
| [10, "hello", 200.3] |
Diccionarios |
| { "edad" : "20", "nombre" : "Dani" } |
Tuplas (secuencia de objetos ordenada e inmutable) |
| (10, "hello", 200.3) |
Conjuntos (colección de objetos únicos desordenada) |
| { "a", "b" } |
Booleanos (indicador de valor lógico) |
| True o False |
2.2. Operaciones con números
Python también proporciona una serie de operadores que se pueden utilizar para realizar operaciones matemáticas en números:
Operador | Función |
---|---|
+, -, *, /, % | Suma, resta, producto, división y módulo (devuelve el resto de la división), respectivamente. |
| Python permite mostrar números negativos. |
| Valor absoluto del número. |
| |
| Devuelve el mayor número de los que se pasan como argumentos. El contrario sería |
| Redondea números a un número especificado de decimales. Por ejemplo, redondea el número pi a 2 decimales. |
| Redondea las unidades hacia abajo. Necesita |
| Redondea las unidades hacia arriba. Necesita |
| Devuelve la raíz cuadrada de un número. Necesita |
| Valor numérico de Pi. Necesita |
| Convierte números a hexadecimal. |
| Convierte números a binario. |
2.3. Asignación de variables
Cuando creamos variables en Python, debemos seguir ciertas reglas:
Los nombres de las variables no pueden comenzar con números.
No puede haber espacios en el nombre de la variable.
No se pueden usar los siguientes símbolos:
: ''' <> / , ? | \ ( ) ! @ # $ % ^ & * ~ - +
Es considerado una buena práctica utilizar nombres de variables en minúsculas.
Python utiliza la tipificación dinámica, lo que significa que no es necesario indicar el tipo de dato (int, double, ...) ya que Python interpretará el tipo de dato en función del valor que se le asigne. Por ejemplo, podríamos crear una variable que contenga un tipo de dato y luego en el código asignarle otro tipo de datos:
Al escribir type(variable)
en Python, nos muestra el tipo (int, string, bool...) de la variable.
2.4. Imprimir en pantalla
La función utilizada para imprimir en pantalla es print()
:
Podemos concatenar variables que contienen cadenas de texto o métodos/funciones que devuelvan un valor utilizando el operador +
, por ejemplo:
El procedimiento anterior puede no ser muy eficiente. Por ello, Python permite dar formato a la función print()
utilizando la letra f
después del primer paréntesis de la función print()
. Así, mediante llaves {}
podemos colocar las funciones, variables o cualquier elemento que queremos mostrar en pantalla. Esto es válido a partir de la versión de Python 3. Aplicando este formato al ejemplo anterior, el resultado sería el siguiente:
2.5. Cadenas de texto (String)
Definimos a un string como una cadena de caracteres, por ejemplo:
Al igual que las listas, el índice de una variable de tipo string comienza en 0, pero a diferencia de las listas, los strings son inmutables, lo que significa que no podemos utilizar el indexado para modificar un elemento individual del string.
2.5.1. Funciones de las cadenas de texto (String)
Las variables de tipo string en Python tienen una serie de funciones incorporadas que permiten manipular y analizar el contenido de la cadena. Aquí hay algunas de las funciones más comunes:
Función | Definición |
---|---|
| Permite transformar una variable en string. |
| Devuelve la variable string copiandola ‘x’ veces, siendo ‘x’ un número entero. |
| Permite quedarte con una parte del string desde el índice hasta el final del string. |
| Permite coger todo el string pero con un tamaño de paso (step size) de 2, es decir, voy cogiendo caracteres de X en X, siendo X un número entero. |
| Permite invertir un string. |
| Convierte el string entero en minúsculas. |
| Convierte el string entero en mayúsculas. |
| Devuelve True si todo el string está en mayúsculas y devuelve False en caso contrario. |
| Convierte el string a mayúsculas y devuelve True si todo el string está en mayúsculas. |
| Permite crear una lista con el string, donde cada elemento de la lista es cada palabra separada del espacio. Si ponemos por ejemplo |
| Devuelve el número de caracteres del string ( tamaño del string ). |
| Devuelve el primer índice del string donde se encuentra el parámetro que se le pasa. |
| Por ejemplo, si mi string es "Hola buenas", reemplaza el "buenas" de mi string, por "me llamo Daniel". |
| Cuenta el número de veces que aparece un carácter. |
variable.find('x') | Devuelve la primera posición en la que encuentra el carácter ‘x’. |
| Devuelve True si todos los caracteres son alfanuméricos. |
| Devuelve True si todos los caracteres son alfabéticos. |
| Devuelve True si todos los caracteres están en minúscula. |
| Devuelve True si todos los caracteres son espacios en blanco. |
| Devuelve True si la primera letra de cada palabra está en mayúsculas. |
| Devuelve True si todos los caracteres están en mayúsculas. |
| Corta la frase cuando encuentra el carácter ‘x’ y la divide en varias partes. |
| Divide la frase en 2 partes cuando se encuentra el carácter ‘x’ introducido. |
| Elimina los espacios al principio y al final de la cadena. |
A continuación se muestra un ejemplo de cómo contar la frecuencia de cada carácter en una cadena de texto en Python. El código es el siguiente:
Este código cuenta la frecuencia de cada carácter en la cadena de texto ingresada por el usuario. También muestra cómo usar el método count()
de las cadenas de texto para contar la aparición de un carácter específico. Este método es sensible a mayúsculas y minúsculas. Por lo tanto, si queremos contar la aparición de un carácter sin importar si está en mayúsculas o minúsculas, podemos convertir la cadena de texto a minúsculas o mayúsculas antes de usar el método count()
. Por ejemplo, s.lower().count('a')
.
2.5.2. Formato de impresión en pantalla
Si queremos mostrar un dato de tipo float
(número con coma flotante) pero con una cantidad determinada de decimales, podemos especificarlo con el siguiente formato: {valor_float:.precision}
Por ejemplo, si queremos mostrar el número pi con 5 decimales, podemos hacerlo de la siguiente manera:
2.6. Listas
Las listas en Python son una secuencia ordenada y mutable que puede almacenar elementos de manera dinámica y de diferentes tipos. Que una lista sea ordenada significa que cada posición tiene un índice, siendo el índice de la posición inicial el 0. El término mutable hace referencia a que los elementos almacenados en la lista pueden ser modificados a lo largo del programa. Por último, que sea dinámica significa que la lista no tiene un tamaño fijo, por lo que este puede variar a lo largo del código. Por ejemplo:
También podemos inicializar una lista sin valores:
Para acceder a los elementos de la lista, podemos hacerlo de la siguiente manera:
2.6.1. Operaciones / Funciones
Función | Definición |
---|---|
| Permite cambiar el dato de la lista que ocupa ese índice por el dato que se le asigne a continuación. |
| Permite concatenar listas o se puede usar el signo '+'. Permite agregar los objetos de una lista a otra lista sin tener una lista dentro de otra lista. |
| Permite añadir un objeto al final de la lista. |
| Primer parámetro es el índice de la lista ( posición a insertar en la lista ) y el segundo es el elemento a añadir. |
| Para eliminar el objeto de la lista. |
| Permite vaciar la lista. |
| Elimina el último elemento de la lista o se le pude introducir un índice, así borraría el elemento de la lista que ocupe ese índice. |
| Me dice el índice del parámetro dentro de la lista. |
| Devuelve el número de veces que se repite el dato en la lista. |
| Permite ordenar una lista de menor a mayor. |
| Invierte la lista. |
| Permite copiar los atributos de la |
| Muestra el máximo de una lista, para hacer lo contrario → |
| Podemos eliminar el dato encontrado en el índice ‘x’ de la lista. |
Python permite utilizar bucles for
directamente en una lista, lo cual puede ser más eficiente que un bucle for
común. Aquí tienes un ejemplo:
2.6.2. Listas en 2D (matrices)
Python permite crear listas dentro de otras listas, creando una especie de malla o matriz. Aquí tienes un ejemplo:
Las librerías Numpy y Pandas son muy útiles para manipular datos y realizar operaciones con datos, entre ellas, matrices.
2.7. Diccionarios
Un diccionario en Python es una colección de datos no ordenada, mutable e indexada. Los diccionarios están escritos con corchetes y cuentan con claves (keys) y valores (values). Cada clave tiene que estar asociada a un valor único. Por ejemplo:
Con el diccionario anterior, vamos a mostrar cómo acceder a las claves del diccionario:
En caso de buscar un valor de clave no encontrado en un diccionario podemos utilizar la función get()
, que permite mostrar un texto en caso de error:
2.7.1. Funciones de los diccionarios
Los diccionarios en Python tienen varias funciones incorporadas que permiten manipular y acceder a sus elementos. Aquí tienes algunas de las más comunes:
diccionario.items()
: Devuelve una vista de los pares clave-valor del diccionario.diccionario.keys()
: Devuelve una vista de las claves del diccionario.diccionario.values()
: Devuelve una vista de los valores del diccionario.
Además, los diccionarios en Python pueden contener otros diccionarios, lo que permite crear estructuras de datos complejas. Por ejemplo:
Para acceder al valor de 'insideKey' en el diccionario anidado, puedes hacerlo de la siguiente manera:
También puedes iterar sobre las claves, los valores y los elementos (pares clave-valor) de un diccionario. Aquí tienes un ejemplo:
Puedes combinar listas y diccionarios para crear estructuras de datos más complejas. Por ejemplo, puedes tener una lista de diccionarios, donde cada diccionario representa a un cliente y sus animales:
2.8. Tuplas
Las tuplas en Python son similares a las listas, pero con la principal diferencia de que los elementos que almacenan son inmutables, es decir, no pueden sufrir modificaciones una vez creados. Una de las ventajas principales de las tuplas es que suelen ser más rápidas de iterar sobre ellas en comparación con las listas. Por ejemplo:
2.8.1. Funciones de las tuplas
Las tuplas en Python tienen algunas funciones incorporadas que permiten manipular y acceder a sus elementos. Aquí tienes las más comunes:
tupla.count(x)
: Devuelve el número de veces que 'x' aparece en la tupla.tupla.index(x)
: Devuelve el primer índice donde se encuentra 'x'.
También puedes crear una lista de tuplas. Por ejemplo:
2.9. Conjuntos (Sets)
Un conjunto (set
) en Python es una colección desordenada de elementos únicos. Esto significa que cada elemento puede aparecer solo una vez en un conjunto. Aquí tienes un ejemplo:
2.9.1. Funciones de los conjuntos
Los conjuntos en Python tienen varias funciones incorporadas que permiten manipular y acceder a sus elementos. Aquí tienes algunas de las más comunes:
Función | Definición |
---|---|
| Añadir un elemento ‘x’ a un set. |
| Borrar todos los elementos de un set. |
| Realizar una copia del set. Los cambios que se hagan en el set original no se verán afectados en la copia. |
| Devolver la diferencia entre dos o mas sets, por ejemplo, un set que contenga un valor no encontrado en otro set. |
| Borrar los elementos de un set que coinciden con los elementos de otro set. |
| Descartar un elemento del set. En el caso de que no encuentre el dato no se produce ningún cambio. |
| Realizar la intersección de 2 o mas sets. Recordar que la intersección devuelve los elementos que son comunes en los sets. |
| Ver si un set contiene a otro set. Devuelve True o False. |
| Unión de dos sets. Recordar que la unión consiste en combinar todos los elementos de los sets sin repetir ningún elemento. |
2.10. Booleanos (Bool)
Los booleanos son operadores que permiten transmitir declaraciones de verdadero (True) o falso (False). Los operadores booleanos son muy útiles en el control de flujo y lógica. Veremos diferentes casos de usos en los ejemplos siguientes.
2.11. Introducción de datos
Python ofrece la posibilidad de obtener información introducida por el usuario con la función input(...)
. Es importante tener en cuenta que la función input()
transforma todo el contenido pasado a tipo string. Esto es relevante si posteriormente necesitamos manipular datos con un tipo de dato concreto. Por ejemplo:
Para convertir un input en un número y no como un string, tenemos que realizar una conversión de tipo de dato. Este procedimiento recibe el nombre de “casting”. Por ejemplo:
2.12. Manejo de archivos
Podemos abrir un fichero usando la función open()
:
Python permite asignar diferentes permisos (escritura/lectura/ambas...) al fichero, algunos de estos permisos son:
Permiso | Definición |
---|---|
r | Solo lectura. |
w | Solo escritura, reescribirá los archivos existentes o creará uno nuevo. |
a | Para añadir información al final del archivo. |
r+ | Lectura y escritura. |
w+ | Escritura y lectura, reescribirá los archivos existentes o creará uno nuevo. |
wb | Modo archivo, escritura y binario. |
2.12.1. Lectura de archivos
Para poder leer un fichero podemos utilizar algunas funciones como:
Función | Definición |
---|---|
| Devuelve un booleano para saber si se puede leer o no el fichero. |
| Muestra toda la información del fichero. |
| Lee la primera línea del fichero. |
| Lee todas las líneas del fichero y las inserta en una lista. |
Por ejemplo:
Alternativa:
Si leemos archivos directamente con métodos como read()
, al leer de nuevo el fichero no aparecerá nada, para solucionarlo hay que usar:
nombre_fichero.seek(0)
→ Permite poner el cursor al principio del fichero.
Otra forma de abrir un fichero y operar con él sería:
2.12.2. Escritura de archivos
Un ejemplo de cómo escribir en un fichero sería:
3. Operadores
3.1. Operadores de comparación
En Python, además de poder comparar números, también podemos comparar cadenas de texto (string
), distinguiendo entre mayúsculas y minúsculas. Aquí tienes una lista de los operadores de comparación más comunes:
Expresión | Definición |
---|---|
A == B | A es igual a B. |
A != B | A es distinto que B. |
A < B | A es menor que B. |
A <= B | A es menor o igual que B. |
A > B | A es mayor que B. |
A >= B | A es mayor o igual que B. |
3.2. Operadores lógicos
Los operadores lógicos se pueden utilizar para combinar operadores de comparación. Los operadores lógicos en Python son:
Expresión | Definición |
---|---|
| Todas las condiciones han de ser verdaderas para que sea True. Si una de las condiciones es False, el resultado será False. |
| Basta con que una de las condiciones sea True para que el resultado sea True. |
| Sirve para negar la condición. |
3.3. Operadores útiles
Python ofrece una serie de operadores útiles para trabajar con listas y números. Aquí tienes algunos ejemplos:
Para cambiar el orden de manera aleatoria de una lista:
Para obtener un número aleatorio de un rango establecido:
4. Declaraciones if
, elif
y else
if
, elif
y else
Las declaraciones if
, elif
y else
se utilizan en Python para controlar el flujo de ejecución del programa en función de ciertas condiciones.
La sintaxis de una declaración if
es la siguiente:
La sintaxis de una declaración if/else
es la siguiente:
La sintaxis de una declaración if/elif/else
con varias condiciones es la siguiente:
Aquí tienes un ejemplo en el que se utiliza una declaración if
y else
para comprobar si un elemento se encuentra dentro de una lista:
En el primer ejemplo, se comprueba si el número 1 está en la lista. En el segundo ejemplo, se comprueba si el valor 345 está entre las claves del diccionario d
. En ambos casos, se imprime un mensaje en función del resultado de la comprobación. Si la condición es verdadera, se imprime un mensaje indicando que el elemento se encuentra en la lista o en el diccionario. Si la condición es falsa, se imprime un mensaje indicando que el elemento no se encuentra en la lista o en el diccionario.
5. Bucles
5.1. Bucle for
for
Muchos objetos en Python son iterables, es decir, podemos recorrer cada uno de sus elementos. Un ejemplo podría ser recorrer cada elemento que compone una lista o los caracteres que componen un string. Usamos entonces los bucles for
para iterar sobre dichos elementos. Aquí tienes la sintaxis:
Podemos establecer un rango de recorrido para el bucle con la función range(x, y, z)
, donde 'x' es el inicio, 'y' es el fin - 1 y 'z' es el tamaño de paso.
Por ejemplo:
La función zip()
permite asignar un índice a un valor de dos listas diferentes para formar una tupla. Hay que tener en cuenta que si las listas tienen diferentes tamaños, se hará un zip con el máximo de elementos de la lista con menor número de elementos.
zip(x, y, ...)
→ Se pueden meter tantas listas como se requieran.
Por ejemplo:
Otros ejemplos de bucles for
:
5.2. Bucle while
while
El bucle while
realiza un bucle mientras se cumpla la condición. Aquí tienes la sintaxis:
También existe la posibilidad de combinarlo con un else
:
5.3. break
, continue
y pass
break
, continue
y pass
break
→ Rompe con el bucle que se esté ejecutando en ese momento. Por ejemplo:
continue
→ Va a la parte superior del bucle de cierre más cercano. Por ejemplo:
pass
→ No hace nada en el bucle y se utiliza para evitar errores cuando se requiere una declaración sintáctica pero no se quiere ejecutar ningún código. Es útil como un marcador de posición cuando se está diseñando código a nivel de esquema. Por ejemplo:
En este ejemplo, la declaración pass
permite que el bucle for
continúe su iteración normalmente después de la letra 'h'. Sin la declaración pass
, habría un error porque Python espera una declaración después del if
pero no encuentra ninguna. Con pass
, Python tiene una declaración que no hace nada, lo que evita el error.
6. Métodos y funciones
6.1. Métodos
Los métodos son funciones que están asociadas a un objeto y pueden actuar sobre el objeto mismo. Cada tipo de objeto tiene un conjunto de métodos asociados. Por ejemplo, los objetos de tipo str
(cadenas de texto) tienen métodos para convertir a mayúsculas, dividir la cadena en palabras, reemplazar una subcadena, etc.
Para obtener una lista completa de los métodos disponibles para un tipo de objeto en particular, puedes usar la función dir()
. Por ejemplo, dir(str)
te dará una lista de todos los métodos que puedes usar en objetos de tipo str
.
Además, puedes obtener ayuda sobre un método específico usando la función help()
. Por ejemplo, help(str.upper)
te dará información sobre el método upper()
que se puede usar en cadenas de texto.
Para obtener información más detallada y actualizada sobre los métodos en Python, te recomiendo visitar la documentación oficial de Python en https://docs.python.org/.
6.2. Funciones
Las funciones en Python son bloques de código reutilizables que realizan una tarea específica. Puedes definir tus propias funciones usando la palabra clave def
, seguida del nombre de la función y una lista de parámetros entre paréntesis. El código de la función va indentado después de los dos puntos.
Aquí tienes un ejemplo de cómo definir y usar una función en Python:
En este ejemplo, saludo
es una función que toma un parámetro, nombre
, y devuelve una cadena de texto que es un saludo a ese nombre.
Las funciones pueden tomar cualquier número de parámetros, y estos parámetros pueden tener valores predeterminados. Si un parámetro tiene un valor predeterminado, puedes omitir ese parámetro cuando llamas a la función. Aquí tienes un ejemplo:
En este ejemplo, nombre
tiene un valor predeterminado de "Mundo"
. Si llamas a saludo()
sin ningún argumento, usará el valor predeterminado. Si proporcionas un argumento, ese argumento reemplazará el valor predeterminado.
Las funciones son una excelente manera de organizar tu código y hacerlo más legible y reutilizable. También pueden ayudarte a dividir problemas complejos en partes más manejables.
6.2.1. Funciones con Lógica
Las funciones en Python pueden contener una variedad de estructuras de control, como bucles y llamadas a otras funciones. Aquí te presento algunos ejemplos:
Función para comprobar una lista: Esta función toma una lista de números como entrada y separa los números pares e impares en dos conjuntos diferentes:
Función con tuplas: Este ejemplo muestra una función que determina el trabajador con más horas trabajadas:
Funciones que llaman a otras funciones: En este ejemplo, se muestra un juego simple donde las funciones llaman a otras funciones. Se utiliza la función
shuffle()
de Python, que reordena una lista de manera aleatoria:
Estos ejemplos muestran cómo las funciones en Python pueden contener lógica compleja y cómo pueden interactuar entre sí para realizar tareas más grandes.
6.3. Argumentos Arbitrarios: *Args y **Kwargs
En Python, los términos *args
y **kwargs
se utilizan en la definición de funciones para permitir que estas acepten un número arbitrario de argumentos. Veamos algunos ejemplos:
6.3.1. Funciones con Argumentos Posicionales
En el siguiente ejemplo, a
y b
son argumentos posicionales. La función mifuncion
toma estos dos argumentos, los suma y luego multiplica el resultado por 0.05:
Sin embargo, si quisiéramos que esta función pudiera manejar más de dos números, tendríamos que modificar la definición de la función para incluir más parámetros. Una opción sería asignar un valor predeterminado a estos parámetros adicionales:
6.3.2. Funciones con *Args
Aquí es donde *args
resulta útil. Nos permite configurar la función para aceptar un número arbitrario de argumentos:
En este caso, *args
permite tratar la entrada como una tupla de parámetros. Ahora podemos pasar tantos argumentos como queramos. Por defecto, Python toma todos los parámetros que se pasan y los configura como una tupla.
6.3.3. Funciones con **Kwargs
De manera similar, Python ofrece una forma de manejar un número arbitrario de argumentos de palabras clave. En lugar de crear una tupla, crea un diccionario. Para ello, usamos **kwargs
:
6.3.4. Combinando *Args y **Kwargs
También podemos combinar *args
y **kwargs
en la misma función:
En este caso, args
es una tupla de los argumentos posicionales y kwargs
es un diccionario de los argumentos de palabras clave. Esto nos da una gran flexibilidad a la hora de definir funciones en Python.
6.4. Expresiones Lambda, Funciones Map y Filter
Las expresiones Lambda, junto con las funciones map()
y filter()
, son herramientas poderosas en Python que permiten un procesamiento de datos avanzado.
6.4.1. Expresiones Lambda
Las expresiones Lambda son una forma rápida de crear funciones anónimas, es decir, funciones que se utilizan una sola vez.
Esta expresión lambda toma un número, lo eleva al cuadrado y devuelve el resultado.
6.4.2. Función Map
La función map()
aplica una función a cada elemento de una lista, devolviendo una nueva lista con los resultados.
En este ejemplo, la función map()
aplica la expresión lambda a cada elemento de mis_nums
, devolviendo una nueva lista con los cuadrados de los números originales.
6.4.3. Función Filter
La función filter()
filtra los elementos de una lista basándose en una función de filtrado, devolviendo una nueva lista con los elementos que cumplen la condición de filtrado.
En este ejemplo, la función filter()
aplica la expresión lambda a cada elemento de mis_nums
, devolviendo una nueva lista con solo los números pares.
6.4.4. Combinando Lambda, Map y Filter
Las expresiones lambda se utilizan comúnmente junto con las funciones map()
y filter()
, permitiendo un procesamiento de datos más conciso y eficiente.
En este ejemplo, la función map()
aplica la expresión lambda a cada elemento de people
, devolviendo una nueva lista con solo el título y el apellido de cada persona.
Es importante recordar que las expresiones lambda pueden tomar múltiples argumentos, lo que aumenta su flexibilidad y utilidad. Sin embargo, debido a su naturaleza anónima y de un solo uso, las expresiones lambda son más adecuadas para operaciones simples y concisas. Para operaciones más complejas, es recomendable definir una función completa.
6.5. Declaraciones anidadas y alcance del código (Scope)
En Python, es crucial entender cómo se manejan las variables que creamos. Estas variables se almacenan en lo que se conoce como un "alcance" o "scope", que determina la visibilidad de la variable a otras partes del código.
Por ejemplo:
En este ejemplo, la reasignación de x
dentro de la función printer()
no afecta a la asignación global de x
. Esto se debe a la regla de alcance (scope) en Python, que sigue la regla LEGB:
L, Local — Nombres asignados de alguna manera dentro de una función (
def
olambda
) y que no se declaran globales en esa función.E, Enclosing function locals — Nombres en el ámbito local de cualquier y todas las funciones de encierro (
def
olambda
), de interior a exterior.G, Global (module) — Nombres asignados en el nivel superior de un archivo de módulo, o declarados globales en un
def
dentro del archivo.B, Built-in (Python) — Nombres preasignados en el módulo de nombres incorporado:
open
,range
,SyntaxError
, etc.
Este es el orden en el que Python buscará las variables. Aquí hay un ejemplo de cómo funciona:
En este ejemplo, la función hola()
mostrará primero la variable local "Carlitos". Si comentamos la asignación local, cogerá la variable de encierro local "Daniel". Y si también comentamos esa asignación, cogerá la variable global "Esto es un string global".
Ahora, veamos qué sucede cuando reasignamos una variable global dentro de una función. Si hacemos una reasignación dentro de la función, por el alcance (scope), el valor de reasignación solo se mantiene dentro de la función. Una vez que salimos de ella, el valor de la variable vuelve a ser el valor que se le asignó al principio. Para cambiar esto, podemos usar la palabra clave global
, como en el siguiente ejemplo:
Sin embargo, se recomienda evitar el uso de la palabra clave global
a menos que sea absolutamente necesario. Es más seguro devolver un objeto y luego asignarlo a la variable. De esta manera, evitamos sobrescribir la variable global dentro de una función sin siquiera saberlo.
6.6. Validación de Datos
Cuando se crean funciones que toman valores de entrada del usuario, es importante verificar esas entradas para asegurarse de que son correctas. Esto se conoce como validación de datos.
La función input()
en Python puede ser un poco complicada porque espera la interacción del usuario. Si se ejecuta accidentalmente dos veces, el programa puede quedarse esperando una respuesta que no llega. En ese caso, en Jupyter tendrías que reiniciar el kernel, teniendo en cuenta que todas las variables anteriores se borrarán y tendrías que ejecutarlas de nuevo.
Una forma cómoda de validar datos es utilizar bucles while
para pedir al usuario que introduzca un valor repetidamente cuando este no es válido. Aquí tienes un ejemplo:
En este ejemplo, la función eleccion_usuario()
pide al usuario que introduzca un número entre 1 y 10. Si el valor introducido no es un número o si no está en el rango correcto, la función le pide al usuario que introduzca un nuevo valor.
Si quieres limpiar la consola cuando el usuario introduce valores incorrectos, puedes importar y usar la biblioteca IPython.display
y usar la función clear_output()
:
Esta función borra la salida de la celda actual en un cuaderno Jupyter, lo que puede ser útil para mantener la interfaz de usuario limpia. Sin embargo, ten en cuenta que clear_output()
solo funciona en cuadernos Jupyter y no en otros entornos de Python.
7. Programación Orientada a Objetos (POO)
7.1. Introducción
La Programación Orientada a Objetos (POO) permite crear objetos propios que tienen métodos y atributos. Estos métodos actúan como funciones que usan información sobre el objeto, así como el objeto mismo (self
), para realizar operaciones o cambiar el estado del objeto. La POO permite crear código que es repetible y organizado, facilitando la creación de programas flexibles y escalables. A menudo, al usar bibliotecas externas, estas emplean la POO. Aquí tienes un ejemplo sencillo para entender la sintaxis:
7.2. Atributos y Clases
La clase es un plano que define la naturaleza de un objeto. Podemos construir un objeto en una instancia, esta instancia es un objeto específico creado a partir de una clase en particular. Aquí tienes un ejemplo de una clase junto con sus atributos y sus métodos:
En este ejemplo, creamos una clase Coche
con varios atributos y métodos. Luego creamos una instancia de Coche
, mi_coche
, y utilizamos sus métodos y atributos. La Programación Orientada a Objetos nos permite organizar nuestro código de manera eficiente y reutilizable.
7.3. Atributos de la Clase y Métodos
Los atributos de los objetos de una clase son los mismos para cualquier instancia de la clase. Los métodos, por otro lado, son acciones que realizamos con el objeto que hemos creado. Aquí tienes un ejemplo:
7.4. Herencia y Polimorfismo
La herencia es una forma de crear nuevas clases utilizando clases ya definidas. La principal ventaja de la herencia es la reutilización del código, lo que reduce la complejidad del programa. Aquí tienes un ejemplo de herencia:
El polimorfismo se refiere a la forma en que diferentes clases de objetos pueden compartir el mismo nombre de método. Luego, esos métodos se pueden llamar desde el mismo lugar, aunque se puedan pasar una variedad de objetos diferentes. Aquí tienes un ejemplo:
Una práctica más común es usar clases abstractas combinadas con herencia. Las clases abstractas son aquellas que no esperan ser instanciadas. Están diseñadas para servir como clase base. Aquí tienes un ejemplo:
Uno de los ejemplos más realistas del polimorfismo podría ser crear una clase base que implemente el método de abrir un archivo en general, pero con diferentes clases derivadas que se encarguen de abrir archivos con formatos específicos.
8. Módulos y Paquetes
8.1. Pip install y PyPi
PIP es un sistema de gestión de paquetes utilizado para instalar y administrar paquetes de software escritos en Python. Por ejemplo, puedes usar PIP para instalar paquetes desde PyPi, que es un repositorio de software para el lenguaje de programación Python.
PyPi es un repositorio para paquetes de Python de código abierto de terceros. Las bibliotecas que hemos estado utilizando hasta ahora son bibliotecas integradas, pero puedes utilizar el comando pip install
en la terminal junto con el nombre del paquete que deseas instalar. Por ejemplo:
8.2. Módulos y Paquetes
Un módulo es simplemente un archivo de Python con la extensión .py, y puede contener funciones, clases y variables. Un paquete, por otro lado, es una forma de organizar módulos relacionados en una carpeta jerárquica. La carpeta del paquete debe contener un archivo especial llamado __init__.py
, que puede estar vacío pero debe estar presente en la carpeta.
Aquí tienes un ejemplo de cómo puedes organizar tu código en módulos y paquetes:
8.3. Name y "main"
Cuando ejecutas un script de Python, Python asigna al nombre __name__
el valor "__main__"
. Pero si este código se importa como un módulo en otro script, el atributo __name__
se asigna al nombre del archivo del script (sin la extensión .py). Aquí tienes un ejemplo:
En este ejemplo, si ejecutas one79.py
, verás que __name__
se establece en "__main__"
para one79.py
y se establece en "two79"
para two79.py
. Esto es útil si quieres que cierto código se ejecute solo cuando el archivo se ejecuta directamente, y no cuando se importa como un módulo.
9. Manejo de errores y excepciones
9.1. Errores y manejo de excepciones
El manejo de errores es una estrategia que nos permite planificar y gestionar posibles errores que puedan surgir en nuestro código. Por ejemplo, si un usuario intenta escribir en un archivo que se ha abierto en modo de solo lectura y no hay ninguna declaración de error en el código, el programa entero se detendrá. Para evitar esto, utilizamos el manejo de excepciones, que nos permite continuar con el programa, notificar el error y seguir con el código.
Existen tres palabras clave para el manejo de errores en Python:
try
: Este es el bloque de código que se intentará ejecutar (puede llevar a un error).except
: Bloque de código que se ejecutará en caso de que haya un error en el bloque de prueba (try
).finally
: Un bloque final de código que se ejecutará independientemente de si hubo un error o no.
Aquí tienes un ejemplo de cómo se utilizan estas palabras clave:
En este otro ejemplo, pediremos constantemente un dato al usuario hasta que introduzca un valor adecuado:
Python tiene más excepciones implementadas que puedes consultar en la documentación, en el apartado "Library → Exceptions".
9.2. Pylint
Las pruebas unitarias son esenciales a medida que expandimos nuestros proyectos con varios archivos o comenzamos a trabajar en equipo. Al realizar cualquier cambio o actualización en el código, podemos ejecutar archivos de prueba para asegurarnos de que el código anterior aún se ejecuta de la manera esperada.
Existen diferentes herramientas para probar el código, pero nos centraremos en dos de ellas:
Pylint: Esta es una biblioteca que analiza el código e informa de posibles problemas.
Unittest: Esta biblioteca incorporada permite probar tus propios programas y comprobar que estás obteniendo los resultados deseados.
Para usar Pylint, ejecuta el siguiente código en la terminal:
9.3. Unittest
Con unittest
, puedes implementar un script en Python que analice los resultados devueltos por tu código y compruebe si son los esperados. Aquí tienes un ejemplo con dos archivos, cap85a.py
y cap85b.py
.
cap85a.py
:
cap85b.py
:
En este ejemplo, unittest
se utiliza para comprobar que la función prueba
del archivo cap85a.py
devuelve el resultado esperado. Si el resultado es el esperado, la prueba pasará. Si no, la prueba fallará y se mostrará un mensaje de error.
10. Decoradores
Los decoradores en Python son una herramienta poderosa que permite "decorar" una función, es decir, modificar su comportamiento sin alterar su código fuente. Esto es útil cuando queremos añadir funcionalidades a una función existente sin modificar su definición.
10.1. Funciones como objetos
En Python, las funciones son objetos de primera clase. Esto significa que pueden ser asignadas a variables, almacenadas en estructuras de datos, pasadas como argumentos a otras funciones e incluso retornadas como valores de otras funciones. Aquí tienes un ejemplo:
En este ejemplo, hemos asignado la función funcion_saludo
a la variable copia
, y luego hemos eliminado funcion_saludo
. A pesar de esto, aún podemos llamar a la función original a través de copia
.
10.2. Definición de un decorador
Un decorador es una función que toma otra función y extiende su comportamiento sin modificar explícitamente su código fuente. Aquí tienes un ejemplo de cómo se define y se usa un decorador:
En este ejemplo, nuevo_decorador
es un decorador que añade dos líneas de impresión antes y después de la ejecución de la función original. La sintaxis @nuevo_decorador
antes de la definición de funcion_necesita_decorador
es lo que aplica el decorador a la función.
10.3. Aplicaciones de los decoradores
Los decoradores tienen muchas aplicaciones. Por ejemplo, se utilizan en el desarrollo web con frameworks como Flask para añadir comportamientos a las funciones de ruta, como requerir que un usuario esté autenticado para acceder a ciertas páginas. También se utilizan para crear loggers, que registran cuándo se llaman a ciertas funciones y con qué argumentos, lo cual es útil para depurar y entender el flujo de ejecución de un programa. En resumen, los decoradores ofrecen una forma elegante y potente de modificar el comportamiento de las funciones en Python.
11. Generadores
Los generadores en Python son una forma eficiente de crear iteradores. A diferencia de las funciones normales, los generadores utilizan la palabra clave yield
en lugar de return
. Esto permite que los generadores produzcan valores de uno en uno, y solo cuando se necesitan, en lugar de calcular todos los valores a la vez y almacenarlos en memoria.
11.1. Funciones generadoras
Una función generadora es una función que utiliza la palabra clave yield
. Cuando se llama a una función generadora, en lugar de ejecutar todo el cuerpo de la función y devolver un resultado, devuelve un objeto generador. Este objeto puede ser iterado para obtener los valores generados por yield
. Aquí tienes un ejemplo de una función generadora que genera los cubos de los números hasta n
:
11.2. Generadores y rendimiento
Los generadores son especialmente útiles cuando trabajamos con grandes cantidades de datos que no caben en memoria. En lugar de generar todos los datos a la vez, los generadores los producen de uno en uno, solo cuando se necesitan. Esto puede mejorar significativamente el rendimiento de nuestro programa.
11.3. Generadores y la función iter()
iter()
La función iter()
en Python convierte un objeto iterable en un iterador. Esto significa que podemos utilizar la función next()
en el objeto para acceder a sus elementos uno a uno. Aquí tienes un ejemplo:
En este ejemplo, hemos convertido la cadena s
en un iterador utilizando la función iter()
. Luego, hemos utilizado la función next()
para obtener el primer elemento del iterador.
12. Módulos avanzados
12.1. Módulos de colección
El módulo collections
en Python implementa tipos de datos de contenedores especializados que proporcionan alternativas a los contenedores generales de Python como dict
, list
, set
, y tuple
.
12.1.1. Counter
Counter
es una subclase de diccionario para contar objetos hashables. Los elementos se almacenan como claves de diccionario y sus recuentos se almacenan como valores de diccionario.
Puedes usar el método most_common()
para obtener los elementos y sus recuentos desde el más común hasta el menos común.
12.1.2. defaultdict
defaultdict
es una subclase de diccionario que proporciona un valor predeterminado para la clave que no existe.
12.1.3. namedtuple
namedtuple
genera subclases de tupla con campos nombrados. Esto permite acceder a los elementos de la tupla por nombre en lugar de índice.
Estos son solo algunos ejemplos de los tipos de contenedores especializados disponibles en el módulo collections
. Estos pueden ser muy útiles para hacer que tu código sea más legible y eficiente.
12.2. Manejo de archivos y directorios
En Python, se utilizan varios módulos para la apertura, lectura y manipulación de archivos y directorios en el sistema operativo. Los módulos principales son:
shutil
os (OS → Sistema Operativo)
Estos módulos permiten realizar operaciones como abrir y leer archivos individuales, navegar por los directorios, mover y eliminar archivos, entre otras.
Además, Python permite listar todos los archivos de un directorio, incluyendo carpetas, subcarpetas y ficheros que contienen:
12.3. Módulo de fecha y hora
El módulo datetime de Python permite crear objetos que contienen información sobre la fecha y la hora, incluyendo la zona horaria. También permite realizar operaciones con fechas y horas, como calcular la diferencia entre dos fechas:
12.4. Módulo math y random
El módulo math en Python proporciona funciones matemáticas definidas por el estándar de C. Algunos ejemplos de su uso son:
El módulo random en Python se utiliza para generar números aleatorios. Algunos ejemplos de su uso son:
12.5. Depurador de Python
El depurador o debugger se emplea para identificar y corregir errores en el código. En lugar de utilizar print()
para ver qué sucede a cada rato, podemos usar el depurador de Python, pdb. Por ejemplo:
12.6. Expresiones regulares
En esta sección, exploraremos expresiones regulares en Python para manipular y buscar patrones en texto.
12.6.1. Búsqueda y manipulación de patrones
Primero, aprenderemos cómo buscar y manipular patrones específicos en cadenas de texto.
12.6.2. Patrones generales
A continuación, exploraremos cómo encontrar patrones más generales en texto.
12.6.3. Patrones de palabras
Finalmente, nos centraremos en encontrar patrones de palabras específicas en un texto.
12.7. Cronometrar el tiempo de ejecución de una función
Para evaluar la eficiencia de nuestro código, podemos medir el tiempo que una función tarda en ejecutar una acción específica. Por ejemplo:
En el código anterior, ambas funciones dan un resultado muy similar, por lo que es difícil ver una diferencia real. Sin embargo, podemos importar la biblioteca timeit, que permite realizar mediciones más precisas con un número de repeticiones y parámetros que podemos asignar. Por ejemplo:
Es importante mencionar que Jupyter permite utilizar funciones mágicas (las funciones mágicas de Jupyter se activan con dos signos de porcentaje al comienzo del bloque de código), una de ellas es la función timeit:
12.8. Comprimir y descomprimir archivos
Aquí tienes un ejemplo de cómo comprimir y descomprimir archivos:
13. Trabajar con ficheros CSV
Los archivos CSV (Comma Separated Values) son un tipo de formato que utilizan Excel y otros programas de bases de datos. Son útiles para la manipulación de datos de un fichero, pero sólo contienen el contenido en crudo, por lo que no podemos obtener imágenes, macros, etc., solo los datos.
En Python, trabajaremos con el módulo csv
incluido en la biblioteca estándar. Otras bibliotecas a considerar para la manipulación de datos en Python serían Pandas, Openpyxl o la API de Google Sheets para Python.
Ahora vamos a ver cómo podemos escribir en un archivo CSV:
14. Trabajar con ficheros JSON
Para trabajar con ficheros JSON, importamos la biblioteca json
.
Python incluso permite cargar ficheros JSON directamente desde una URL:
Última actualización