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:

  • 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 utiliza yield 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ón yield.
  • Cuando la función sale o genera una excepción StopIteration, el generador se considera agotado y las llamadas posteriores a next() generarán la excepción StopIteration.

 

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:

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

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

Inteligencia Artificial

¿Se entienden Do Flamingo y DALL-E? Explorando la simbiosis entre los modelos de generación de subtítulos de imágenes y síntesis de texto a imagen

La investigación multimodal que mejora la comprensión de la computadora de texto e imágenes ha avanzado mucho recient...

Inteligencia Artificial

Descubre Davidsonian Scene Graph un marco de IA revolucionario para evaluar la IA de texto a imagen con precisión

Los modelos de texto a imagen (T2I) son difíciles de evaluar y a menudo dependen de métodos de generación y respuesta...

Ciencia de Datos

Mejorando la inferencia de PyTorch en CPU desde la cuantificación posterior al entrenamiento hasta el multihilo.

Acelere el tiempo de inferencia en CPU con la selección de modelos, la cuantización posterior al entrenamiento con ON...

Inteligencia Artificial

Esta investigación de Aprendizaje Automático desarrolla un modelo de IA para eliminar de manera efectiva los sesgos en un conjunto de datos.

La recopilación de datos puede ser una oportunidad primordial para la introducción no intencionada de sesgos de textu...

Inteligencia Artificial

Conoce a Vchitect un sistema de creación de video de gran escala y generalista de código abierto para aplicaciones de texto a video (T2V) e imagen a video (I2V).

El aumento exponencial en la popularidad de la Inteligencia Artificial (IA) en los últimos tiempos ha llevado a grand...