Cómo Escribir Código Eficiente en Python Un Tutorial para Principiantes
Cómo Escribir Código Eficiente en Python Un Tutorial para Principiantes
Los programadores principiantes disfrutan programando en Python debido a su simplicidad y sintaxis fácil de leer. Sin embargo, escribir código Python eficiente es más complicado de lo que piensas. Requiere comprender algunas de las características del lenguaje (aunque también son fáciles de adquirir).
Si vienes de otro lenguaje de programación como C++ o JavaScript, este tutorial te ayudará a aprender algunos consejos para escribir código eficiente en Python. Pero si eres principiante y estás aprendiendo Python como tu primer (lenguaje de programación), este tutorial te ayudará a escribir un código Pythonico desde el principio.
Nos enfocaremos en lo siguiente:
- Investigadores de UC Berkeley introducen Ghostbuster un método de IA SOTA para detectar texto generado por LLM
- Investigadores de Google DeepMind y YouTube anuncian Lyria un modelo avanzado de generación de música AI
- Cómo crear mapas hexagonales con Matplotlib
- Bucles Pythonicos
- Comprensión de listas y diccionarios
- Gestores de contexto
- Generadores
- Clases de colección
¡Así que sumérgete!
1. Escribir bucles Pythonicos
Comprender los constructores de bucle es importante independientemente del lenguaje en el que estés programando. Si vienes de lenguajes como C++ o JavaScript, es útil aprender cómo escribir bucles Pythonicos.
Genere una secuencia de números con rango
La función range()
genera una secuencia de números, a menudo utilizada como un iterador en bucles.
La función range()
devuelve un objeto de rango que comienza desde 0 por defecto y va hasta (pero no incluye) el número especificado.
Aquí tienes un ejemplo:
for i in range(5): print(i)
Salida >>> 01234
Cuando usas la función range()
, puedes personalizar el punto de inicio, el punto de finalización y el tamaño del paso según sea necesario.
Acceder tanto al índice como al elemento con enumerate
La función enumerate()
es útil cuando quieres tanto el índice como el valor de cada elemento en un iterable.
En este ejemplo, usamos el índice para acceder a la lista fruits
:
fruits = ["manzana", "plátano", "cereza"] for i in range(len(fruits)): print(f"Índice {i}: {fruits[i]}")
Salida >>> Índice 0: manzana Índice 1: plátano Índice 2: cereza
Pero con la función enumerate()
, puedes acceder tanto al índice como al elemento así:
fruits = ["manzana", "plátano", "cereza"] for i, fruit in enumerate(fruits): print(f"Índice {i}: {fruit}")
Salida >>> Índice 0: manzana Índice 1: plátano Índice 2: cereza
Iterar en paralelo sobre múltiples iterables con zip
La función zip()
se utiliza para iterar sobre múltiples iterables en paralelo. Asocia elementos correspondientes de diferentes iterables entre sí.
Considera el siguiente ejemplo donde necesitas recorrer tanto la lista de nombres
como la de puntuaciones
:
nombres = ["Alice", "Bob", "Charlie"] puntuaciones = [95, 89, 78] for i in range(len(nombres)): print(f"{nombres[i]} obtuvo {puntuaciones[i]} puntos.")
Esto imprime:
Salida >>> Alice obtuvo 95 puntos. Bob obtuvo 89 puntos. Charlie obtuvo 78 puntos.
Aquí tienes un bucle mucho más legible con la función zip()
:
names = ["Alice", "Bob", "Charlie"]scores = [95, 89, 78]for name, score in zip(names, scores): print(f"{name} obtuvo {score} puntos.")
Salida >>>Alice obtuvo 95 puntos.Bob obtuvo 89 puntos.Charlie obtuvo 78 puntos.
La versión en Python utilizando zip()
es más elegante y evita la necesidad de indexación manual, lo que hace que el código sea más limpio y legible.
2. Utiliza Comprensiones de Lista y Diccionario
En Python, las comprensiones de lista y de diccionario son una forma concisa de crear listas y diccionarios respectivamente en una sola línea. También pueden incluir declaraciones condicionales para filtrar elementos basados en ciertas condiciones.
Empecemos con la versión del bucle y luego pasaremos a las expresiones de comprensiones tanto para listas como para diccionarios.
Comprensión de Lista en Python
Supongamos que tienes una lista numbers
. Y te gustaría crear una lista squared_numbers
. Puedes usar un bucle for de esta manera:
numbers = [1, 2, 3, 4, 5]squared_numbers = []for num in numbers: squared_numbers.append(num ** 2)print(squared_numbers)
Salida >>> [1, 4, 9, 16, 25]
Pero las comprensiones de lista proporcionan una sintaxis más limpia y sencilla para hacer esto. Te permiten crear una nueva lista aplicando una expresión a cada elemento de un iterable.
Aquí tienes una alternativa concisa utilizando una expresión de comprensión de lista:
numbers = [1, 2, 3, 4, 5]squared_numbers = [num ** 2 for num in numbers]print(squared_numbers)
Salida >>> [1, 4, 9, 16, 25]
Aquí, la comprensión de lista crea una nueva lista que contiene los cuadrados de cada número en la lista numbers
.
Comprensión de Lista con Filtrado Condicional
También puedes agregar condiciones de filtrado dentro de la expresión de la comprensión de lista. Considera este ejemplo:
numbers = [1, 2, 3, 4, 5]odd_numbers = [num for num in numbers if num % 2 != 0]print(odd_numbers)
Salida >>> [1, 3, 5]
En este ejemplo, la comprensión de lista crea una nueva lista que contiene solo los números impares de la lista numbers
.
Comprensión de Diccionario en Python
Con una sintaxis similar a la comprensión de lista, la comprensión de diccionario te permite crear diccionarios a partir de iterables existentes.
Supongamos que tienes una lista fruits
. Te gustaría crear un diccionario con pares clave-valor de fruta:len(fruta)
.
Así es cómo puedes hacer esto con un bucle for:
fruits = ["manzana", "plátano", "cereza", "dátil"]fruit_lengths = {}for fruit in fruits: fruit_lengths[fruit] = len(fruit)print(fruit_lengths)
Salida >>> {'manzana': 5, 'plátano': 6, 'cereza': 6, 'fecha': 4}
Ahora escribamos la equivalencia con comprensión de diccionarios:
frutas = ["manzana", "plátano", "cereza", "fecha"]longitudes_frutas = {fruta: len(fruta) for fruta in frutas}print(longitudes_frutas)
Salida >>> {'manzana': 5, 'plátano': 6, 'cereza': 6, 'fecha': 4}
Esta comprensión de diccionario crea un diccionario donde las claves son las frutas y los valores son las longitudes de los nombres de las frutas.
Comprensión de Diccionario con Filtrado Condicional
Modifiquemos nuestra expresión de comprensión de diccionario para incluir una condición:
frutas = ["manzana", "plátano", "cereza", "fecha"]frutas_largas = {fruta: len(fruta) for fruta in frutas if len(fruta) > 5}print(frutas_largas)
Salida >>> {'plátano': 6, 'cereza': 6}
Aquí, la comprensión de diccionario crea un diccionario con los nombres de las frutas como claves y sus longitudes como valores, pero solo para las frutas con nombres de más de 5 caracteres.
3. Utilice Gestores de Contexto para el Manipulado Eficiente de Recursos
Los gestores de contexto en Python te ayudan a gestionar los recursos de manera eficiente. Con los gestores de contexto, puedes configurar y liberar (limpiar) los recursos fácilmente. El ejemplo más simple y común de gestores de contexto es el manejo de archivos.
Echa un vistazo al fragmento de código a continuación:
nombre_archivo = 'algúnarchivo.txt'archivo = open(nombre_archivo,'w')archivo.write('Algo')
No cierra el descriptor de archivo, lo que resulta en una pérdida de recursos.
print(archivo.closed)Salida >>> False
Probablemente harías lo siguiente:
nombre_archivo = 'algúnarchivo.txt'archivo = open(nombre_archivo,'w')archivo.write('Algo')archivo.close()
Aunque esto intenta cerrar el descriptor, no tiene en cuenta los errores que pueden surgir durante la operación de escritura.
Bueno, ahora puedes implementar el manejo de excepciones para intentar abrir un archivo y escribir algo en ausencia de errores:
nombre_archivo = 'algúnarchivo.txt'archivo = open(nombre_archivo,'w')try: archivo.write('Algo')finally: archivo.close()
Pero esto es verboso. Ahora mira la siguiente versión que utiliza la declaración with
que es admitida por la función open()
que es un gestor de contexto:
nombre_archivo = 'algúnarchivo.txt'with open(nombre_archivo, 'w') as archivo: archivo.write('Algo')print(archivo.closed)
Salida >>> True
Utilizamos la declaración with
para crear un contexto en el que se abre el archivo. Esto asegura que el archivo se cierre correctamente cuando la ejecución sale del bloque with
, incluso si se produce una excepción durante la operación.
4. Utilice Generadores para el Procesamiento Eficiente de Memoria
Los generadores proporcionan una forma elegante de trabajar con conjuntos de datos grandes o secuencias infinitas, mejorando la eficiencia del código y reduciendo el consumo de memoria.
¿Qué Son los Generadores?
Los generadores son funciones que utilizan la palabra clave yield
para devolver valores uno a la vez, preservando su estado interno entre invocaciones. A diferencia de las funciones regulares que calculan todos los valores de una vez y devuelven una lista completa, los generadores calculan y devuelven valores sobre la marcha a medida que se solicitan, lo que los hace adecuados para procesar secuencias grandes.
¿Cómo funcionan los generadores?
Aprendamos cómo funcionan los generadores:
- Una función generadora se define como una función regular, pero en lugar de usar la palabra clave
return
, se utilizayield
para devolver un valor. - Cuando se llama a una función generadora, devuelve un objeto generador. Que se puede iterar mediante un bucle o llamando a
next()
. - Cuando se encuentra la declaración
yield
, se guarda el estado de la función y se devuelve el valor generado al llamante. La ejecución de la función se pausa, pero sus variables locales y estado se conservan. - Cuando se llama el método
next()
del generador nuevamente, la ejecución se reanuda desde donde se pausó y la función continúa hasta la siguiente declaraciónyield
. - Cuando la función sale o genera una excepción
StopIteration
, el generador se considera agotado y las llamadas posteriores anext()
generarán la excepciónStopIteration
.
Creación de generadores
Puedes crear generadores utilizando funciones generadoras o expresiones generadoras.
Aquí tienes un ejemplo de una función generadora:
def cuenta_regresiva(n): while n > 0: yield n n -= 1# Utilizando la función generadorafor num in cuenta_regresiva(5): print(num)
Salida >>> 5 4 3 2 1
Las expresiones generadoras son similares a las comprensiones de lista, pero en lugar de crear listas, crean generadores.
# Expresión generadora para crear una secuencia de cuadradossquares = (x ** 2 for x in range(1, 6))# Utilizando la expresión generadorafor square in squares: print(square)
Salida >>> 1 4 9 16 25
5. Aprovecha las clases de colección
Concluiremos el tutorial aprendiendo sobre dos clases de colección útiles:
- NamedTuple
- Counter
Tuplas más legibles con NamedTuple
En Python, una namedtuple en el módulo de colecciones es una subclase de la clase de tupla incorporada. Pero proporciona campos con nombres, lo que la hace más legible y autoexplicativa que las tuplas regulares.
Aquí tienes un ejemplo de cómo crear una tupla simple para un punto en el espacio tridimensional y acceder a los elementos individuales:
# Tupla de un punto en 3Dcoordinate = (1, 2, 3)# Acceso a los datos mediante desempaquetado de tuplasx, y, z = coordinateprint(f"Coordenada X: {x}, Coordenada Y: {y}, Coordenada Z: {z}")
Salida >>> Coordenada X: 1, Coordenada Y: 2, Coordenada Z: 3
Y aquí está la versión con namedtuple:
from collections import namedtuple# Define un namedtuple Coordinate3DCoordinate3D = namedtuple("Coordinate3D", ["x", "y", "z"])# Creando un objeto Coordinate3Dcoordinate = Coordinate3D(1, 2, 3)print(coordinate)# Acceso a los datos utilizando campos con nombreprint(f"Coordenada X: {coordinate.x}, Coordenada Y: {coordinate.y}, Coordenada Z: {coordinate.z}")
Salida >>>Coordinate3D(x=1, y=2, z=3)Coordenada X: 1, Coordenada Y: 2, Coordenada Z: 3
Los NamedTuples, por lo tanto, te permiten escribir código más limpio y fácil de mantener que las tuplas regulares.
Utiliza Counter para simplificar el conteo
Counter es una clase en el módulo de colecciones que está diseñada para contar la frecuencia de los elementos en un iterable, como una lista o una cadena. Devuelve un objeto Counter con pares clave-valor {elemento:conteo}
.
Tomemos el ejemplo de contar las frecuencias de caracteres en una cadena larga.
Este es el enfoque convencional para contar frecuencias de caracteres usando bucles:
word = "incomprehensibilities"# inicializamos un diccionario vacío para contar caractereschar_counts = {}# contamos las frecuencias de los caracteresfor char in word: if char in char_counts: char_counts[char] += 1 else: char_counts[char] = 1# imprimimos el diccionario char_countsprint(char_counts)# encontramos el carácter más comúnmost_common = max(char_counts, key=char_counts.get)print(f"Carácter más común: '{most_common}' (aparece {char_counts[most_common]} veces)")
Iteramos manualmente a través de la cadena, actualizamos un diccionario para contar las frecuencias de los caracteres y encontramos el carácter más común.
Salida >>>{'i': 5, 'n': 2, 'c': 1, 'o': 1, 'm': 1, 'p': 1, 'r': 1, 'e': 3, 'h': 1, 's': 2, 'b': 1, 'l': 1, 't': 1}Carácter más común: 'i' (aparece 5 veces)
Ahora, logremos la misma tarea utilizando la clase Counter con la sintaxis Counter(iterable)
:
from collections import Counterword = "incomprehensibilities"# contamos las frecuencias de los caracteres usando Counterchar_counts = Counter(word)print(char_counts)# encontramos el carácter más comúnmost_common = char_counts.most_common(1)print(f"Carácter más común: '{most_common[0][0]}' (aparece {most_common[0][1]} veces)")
Salida >>>Counter({'i': 5, 'e': 3, 'n': 2, 's': 2, 'c': 1, 'o': 1, 'm': 1, 'p': 1, 'r': 1, 'h': 1, 'b': 1, 'l': 1, 't': 1})Carácter más común: 'i' (aparece 5 veces)
Entonces, Counter
proporciona una forma mucho más sencilla de contar las frecuencias de los caracteres sin necesidad de iteración manual y gestión de diccionarios.
Conclusión
Espero que hayas encontrado algunos consejos útiles para añadir a tu caja de herramientas de Python. Si estás buscando aprender Python o te estás preparando para entrevistas de programación, aquí tienes un par de recursos para ayudarte en tu camino:
- 5 libros gratuitos para ayudarte a dominar Python
- 7 consejos imprescindibles de Python para entrevistas de programación
¡Feliz aprendizaje!
[Bala Priya C](https://twitter.com/balawc27) es una desarrolladora y escritora técnica de India. Le gusta trabajar en la intersección de las matemáticas, la programación, la ciencia de datos y la creación de contenido. Sus áreas de interés y experiencia incluyen DevOps, ciencia de datos y procesamiento de lenguaje natural. Le gusta leer, escribir, programar y tomar café. Actualmente está trabajando en aprender y compartir su conocimiento con la comunidad de desarrolladores mediante tutoriales, guías y más.
We will continue to update Zepes; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- Construir un Equipo Estratégico de AI Ahora es Fácil con AutoGen
- Investigadores de IA de KAIST presentan KTRL+F una tarea de búsqueda en documentos aumentada con conocimiento que requiere la identificación en tiempo real de objetivos semánticos dentro de un documento.
- Mis estadísticas de vida Seguí mis hábitos durante un año y esto es lo que aprendí
- Entendiendo el mantenimiento predictivo Datos de ondas Ingeniería de características (Parte 1)
- Creando un GPT Climático Utilizando la API de Energía de la NASA
- Desmitificar el relleno de datos
- Consultas de lenguaje natural potenciadas por IA para descubrimiento de conocimiento