Course
30 trucos geniales de Python para mejorar el código con ejemplos
La demanda de conocimientos de programación en Python ha crecido en los últimos años. Para ayudarte a desarrollar tus habilidades de programación en Python, hemos recopilado 30 trucos geniales de Python que podrías utilizar para mejorar tu código. Intenta aprender uno cada día durante los próximos 30 días, y consulta nuestro post sobre las mejores prácticas de Python para asegurarte de que tu código es el mejor de su clase.
Si tus conocimientos de Python no están a la altura, también puedes perfeccionarlos con nuestro Curso de Conocimientos de Python.
#1 Rebanar
a = "Hello World!"
print(a[::-1])
"""
!dlroW olleH
"""
La segmentación es una función de Python que se basa en la indexación para permitir a los usuarios acceder a un subconjunto de una secuencia. Un índice es simplemente la posición de un elemento en una secuencia. Si el tipo de secuencia es mutable, puedes utilizar el corte para extraer y modificar datos.
Nota: También podemos utilizar el troceado en una secuencia inmutable, pero si intentamos modificar el troceado se producirá un TypeError.
El formato en el que se implementan los cortes es: secuencia[inicio:parada:paso]. Si no se especifican valores en los parámetros inicio, parada y paso, la secuencia implementará los valores por defecto. Los valores por defecto son:
- "inicio" por defecto 0
- "parada" por defecto es la longitud de la secuencia
- "paso" por defecto a 1 si no se especifican.
Cuando se proporciona con secuencia[inicio:parada], los elementos devueltos serán desde el índice de inicio hasta la parada- 1 (no se incluye el índice de parada).
También podemos pasar índices negativos, que pueden utilizarse para invertir la secuencia. Por ejemplo, en una lista de 4 elementos, el índice 0 es también el índice -4, y el último índice es también -1. En el código de ejemplo anterior, este conocimiento se aplicó al parámetro paso de la secuencia. En consecuencia, la cadena se imprimió hacia atrás, empezando desde el final de la secuencia hasta el índice 0.
#nº 2 Intercambio en el lugar / Asignación simultánea
a = 10
b = 5
print(f"First: {a, b}")
"""
First: (10, 5)
"""
a, b = b, a + 2
print(f"Second: {a, b}")
"""
Second: (5, 12)
"""
Si tu impresión inicial era que el valor de b sería 7 en lugar de 12, has caído en la trampa del intercambio de posiciones.
En Python, podemos desempaquetar iterables a variables en una sola asignación utilizando el desempaquetado automático. Por ejemplo:
a, b, c = [1, 2, 3]
print(a)
print(b)
print(c)
"""
1
2
3
"""
También podemos reunir varios valores en una sola variable utilizando * - este truco de Python se llama empaquetamiento. A continuación se muestra un ejemplo de embalaje.
a, b* = 1, 2, 3
print(a, b)
"""
1 [2, 3]
"""
La combinación de empaquetado y desempaquetado automáticos da lugar a una técnica conocida como asignación simultánea. Podemos utilizar la asignación simultánea para asignar una serie de valores a una serie de variables.
Lista #3 vs. Tuplas
import sys
a = [1, 2, 3, 4, 5]
b = (1, 2, 3, 4, 5)
print(f"List size: {sys.getsizeof(a)} bytes")
print(f"Tuple size: {sys.getsizeof(b)} bytes")
"""
List size: 112 bytes
Tuple size: 96 bytes
"""
La mayoría de los programadores de Python están familiarizados con la estructura de datos lista. No se puede decir lo mismo de las tuplas. Ambos son iterables, permiten la indexación y el almacenamiento de tipos de datos heterogéneos. Pero hay situaciones en las que puede ser preferible utilizar una tupla en lugar de una lista.
En primer lugar, las listas son mutables, lo que significa que podemos modificarlas a nuestro antojo:
a = [1,2,3,4,5]
a[2] = 8
print(a)
"""
[1,2,8,4,5]
"""
En cambio, las tuplas son inmutables, lo que significa que intentar modificarlas provocará un error de tipo TypeError.
Por esta razón, las tuplas son más eficientes en memoria, ya que Python puede asignar el bloque de memoria adecuado que necesitan los datos. En cambio, en una lista, hay que asignar memoria extra por si la ampliamos: esto se llama asignación dinámica de memoria.
TLDR; En situaciones en las que no quieras que se modifiquen los datos, es preferible una estructura de datos de tuplas a una lista, por razones de memoria. Las tuplas también son más rápidas que las listas.
Aprende más sobre las Estructuras de Datos de Python en este tutorial.
Generadores #4
a = [x * 2 for x in range(10)]
b = (x * 2 for x in range(10))
print(a)
print(b)
"""
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
<generator object <genexpr> at 0x7f61f8808b50>
"""
Las comprensiones de lista son la forma pitónica de crear una lista a partir de otro iterable - Es mucho más rápido que utilizar un bucle for. Pero, ¿qué ocurre si accidentalmente cambias los corchetes de [] a ()? Obtienes un objeto generador.
En Python, los corchetes redondeados con lógica de comprensión de listas crean lo que se conoce como objeto generador. Los generadores son un tipo especial de iterables. A diferencia de las listas, no almacenan sus elementos. En su lugar, almacenan instrucciones para generar cada elemento en orden y el estado actual de las iteraciones.
Cada elemento sólo se genera cuando se solicita, mediante una técnica llamada evaluación perezosa. La principal ventaja de este truco de Python utilizando un generador es que utiliza menos memoria, ya que no se construye toda la secuencia a la vez.
#5 Aliasing
a = [1, 2, 3, 4 ,5]
b = a
# Change the 4th index in b
b[4] = 7
print(id(a))
print(id(b))
print(a) # Remember we did not explicitly make changes to a.
"""
2278459070720
2278459070720
[1, 2, 3, 4, 7]
"""
Python es un lenguaje de programación orientado a objetos: todo es un objeto. Por tanto, asignar un objeto a un identificador es crear una referencia al objeto.
Cuando asignamos un identificador a otro identificador, acabamos teniendo dos identificadores que hacen referencia al mismo objeto. Se trata de un concepto conocido como aliasing. Los cambios en un alias afectarán al otro. A veces este comportamiento es deseado, pero a menudo nos pilla desprevenidos.
Una forma de evitarlo es evitar el aliasing cuando se utilizan objetos mutables. Otra solución podría ser crear un clon del objeto original en lugar de una referencia.
La forma más sencilla de crear un clon es aprovechar el troceado:
b = a[:]
Esto creará una nueva referencia a un objeto lista en el identificador b.
Podrías idear muchas otras soluciones, como llamar a list(a) al asignar los datos a otro identificador y utilizar el método copy().
#6 El operador "no
a = []
print(not a)
"""
True
"""
Nuestro siguiente consejo sobre Python es la forma más sencilla de comprobar si tu estructura de datos está vacía utilizando el operador no. La función no es un operador lógico que devuelve Verdadero si la expresión no es verdadera, o bien devolverá Falso: invierte el valor de verdad de las expresiones y objetos booleanos.
Otra forma de utilizarlo es en una sentencia if:
if not a:
# do something...
Cuando a es Verdadero entonces no devolverá falsoy viceversa.
Es difícil de entender, así que inténtalo.
#7 Cuerdas F
first_name = "John"
age = 19
print(f"Hi, I'm {first_name} and I'm {age} years old!")
"""
Hi, I'm John and I'm 19 years old!
"""
Ocasionalmente, puede que necesitemos formatear un objeto cadena; Python 3.6 introdujo una función genial llamada f-cadenas para simplificar este proceso. Es útil comprender cómo se formateaban las cadenas antes de la nueva versión para apreciar mejor el nuevo método.
Así es como solían formatearse las cadenas:
first_name = "John"
age = 19
print("Hi, I'm {} and I'm {} years old!".format(first_name, age))
"""
Hi, I'm John and I'm 19 years old!
"""
Esencialmente, la nueva forma de formatear es más rápida, más legible, más concisa y más difícil de equivocarse.
Otro uso de las cadenas f es imprimir el nombre de un identificador junto con su valor. Se introdujo en Python 3.8.
x = 10
y = 20
print(f"{x = }, {y = }")
"""
x = 10, y = 20
"""
Consulta este tutorial sobre Formateo de cadenas F en Python para saber más.
#8 El parámetro 'end' de las funciones de impresión
a = ["english", "french", "spanish", "german", "twi"]
for language in a:
print(language, end=" ")
"""
english french spanish german twi
"""
Es bastante habitual utilizar un imprimir sin definir ninguno de sus parámetros opcionales. En consecuencia, varios Pythonistas desconocen que puedes controlar la salida hasta cierto punto.
Un parámetro opcional que podemos cambiar es el final. El parámetro final especifica lo que debe mostrarse al final de una llamada a una función imprimir a una sentencia print.
El valor por defecto de fin es "\n", que indica a Python que empiece una nueva línea. En el código anterior, lo cambiamos por espacio. Así, la salida devuelta todos los elementos de nuestra lista se imprimen en la misma línea.
#9 Añadir a tupla
a = (1, 2, [1, 2, 3])
a[2].append(4)
print(a)
"""
(1, 2, [1, 2, 3, 4])
"""
Ya sabemos que las tuplas son inmutables - véase el truco de Python #3 Lista vs. Lista. Tuplas. Si se intentara cambiar el estado de una tupla, se produciría un error de tipo TypeError. Pero, si piensas en un objeto tupla como una secuencia de nombres con enlaces a objetos que no se pueden cambiar, puedes ver las cosas de otra manera.
Los dos primeros elementos de nuestra tupla son enteros: son inmutables. El último elemento de nuestra tupla es una lista, un objeto mutable en Python.
Si consideramos que nuestra lista no es más que otro nombre de una secuencia con un enlace a un objeto que no se puede modificar, entonces nos daríamos cuenta de que la lista aún se puede modificar desde dentro de la tupla.
¿Te recomendamos que lo hagas en la práctica? Probablemente no, pero es una de esas cosas que está bien saber.
#10 Fusionar diccionarios
a = {"a": 1, "b": 2}
b = {"c": 3, "d": 4}
a_and_b = a | b
print(a_and_b)
"""
{"a": 1, "b": 2, "c": 3, "d": 4}
"""
En Python 3.9 y versiones superiores, es posible fusionar diccionarios utilizando | (OR de bits). No hay mucho más que decir sobre este truco concreto de Python, aparte de que es una solución mucho más legible.
#11 Operador ternario / Expresiones de condición
condition = True
name = "John" if condition else "Doe"
print(name)
"""
John
"""
En el código anterior, puedes ver lo que se conoce como operador ternario: también se denomina expresión condicional entre nombres. Utilizamos operadores ternarios para evaluar cosas en función de si una condición es Verdadera o Falso.
Otra forma en la que podríamos haber escrito nuestro código anterior es la siguiente:
condition = True
if condition:
name = "John"
else:
name = "Doe"
print(name)
"""
John
"""
Aunque ambos conjuntos de código producen el mismo resultado, observa cómo el condicional ternario nos permite escribir un código mucho más corto y claro. Es lo que los pitonistas llamarían la forma más "pitónica" de escribir código.
#12 Eliminar duplicados de las listas
a = [1, 1, 2, 3, 4, 5, 5, 5, 6, 7, 2, 2]
print(list(set(a)))
"""
[1, 2, 3, 4, 5, 6, 7]
"""
La forma más sencilla de eliminar los elementos duplicados de una lista es convertirla en un conjunto (y luego volver a convertirla en lista si lo deseas).
Basándose en la mutabilidad, los conjuntos y las listas son bastante similares en Python. Podemos añadir y quitar elementos de ambas estructuras de datos a voluntad, pero siguen siendo extremadamente diferentes.
Las listas son ordenadas, indexadas en base cero y mutables. Los conjuntos no están ordenados ni indexados. Los elementos de un conjunto deben ser de tipo inmutable, aunque el propio conjunto sea mutable: intentar recuperar un elemento mediante un índice o modificar un elemento provocará un error.
Otra diferencia clave entre los conjuntos y las listas es que los conjuntos no pueden contener duplicados. Esto es lo que nos ayudó a eliminar los elementos duplicados de nuestra lista.
#13 Underscore independiente
>>> print(_)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
>>> 1 + 2
3
>>> print(_)
3
El guión bajo (_) es un identificador legal en Python, por lo que es posible utilizarlo para hacer referencia a un objeto. Pero el subrayado también tiene otra responsabilidad: almacenar el resultado de la última evaluación.
La documentación indica que "el intérprete interactivo hace que el resultado de la última evaluación esté disponible en la variable _. (Se almacena en el módulo builtins, junto a funciones incorporadas como imprimir)".
Como no asignamos el subrayado a un objeto antes de llamarlo en la primera línea, obtuvimos un error. Sin embargo, cuando calculamos el resultado de 1 + 2, el intérprete interactivo almacenó el resultado en el identificador _ por nosotros.
#14 Subrayado para ignorar valores
for _ in range(100):
print("The index doesn't matter")
"""
The index doesn't matter
The index doesn't matter
...
"""
En el consejo sobre Python nº 13, descubrimos que el intérprete interactivo hace que el último resultado de una evaluación esté disponible en el identificador de guión bajo (_), pero ése no es su único caso de uso.
También podemos utilizarlo para representar objetos que no nos interesan o que no utilizaríamos en un momento posterior del programa. Esto es importante porque si utilizamos un identificador en lugar de un guión bajo (_) se producirá un error F841 cuando intentemos hacer linting en nuestro programa. Un error F841 simplemente indica que se ha asignado un nombre de variable local pero no se ha utilizado en el programa, lo cual es una mala práctica.
#15 guiones bajos finales
list_ = [0, 1, 2, 3, 4]
global_ = "Hi there"
Continuando con los dos trucos anteriores, el uso del guión bajo (_) en Python, otra de sus finalidades es evitar conflictos con las palabras clave de Python.
La PEP 8 menciona que el guión bajo final (_) debe "utilizarse por convención para evitar conflictos con las palabras clave de Python". También afirma que "generalmente es mejor añadir un guión bajo final en lugar de utilizar una abreviatura o una corrupción ortográfica". Por tanto, list_ es mejor que lst".
#16 Subrayados principales
class Example:
def __init__(self):
self._internal = 2
self.external = 20
A menudo verás que los programadores experimentados de Python tienden a anteponer un guión bajo a un identificador o nombre de método, y por una buena razón.
El guión bajo antepuesto a un identificador o método tiene un significado oculto: esta variable o método sólo está destinado a uso interno. Esencialmente, es una exención de responsabilidad para otros programadores que se ha definido en la PEP 8 pero que Python no aplica. Por tanto, los subrayados iniciales son un indicador débil.
A diferencia de Java, Python no distingue claramente entre variables privadas y públicas. En otras palabras, sólo tiene significado porque la comunidad Python ha acordado que lo tenga. Su inclusión no influye en el comportamiento de tus programas.
#17 Underscore Visual
Este es el último consejo sobre los guiones bajos; Hasta ahora, hemos cubierto tres casos de uso diferentes para el guión bajo, pero puedes consultar nuestro tutorial para saber más sobre la función del guión bajo(_) en Python.
number = 1_500_000
print(number)
"""
15000000
"""
Otra forma de utilizar el guión bajo es como separador visual para la agrupación de dígitos en los literales de números integrales, de coma flotante y complejos; esto se introdujo en Python 3.6.
La idea era ayudar a la legibilidad de los literales largos, o literales cuyo valor debe separarse claramente en partes - puedes leer más sobre ello en PEP 515.
#18 __name__ == "__main__"
if __name__ == "__main__":
print("Read on to understand what is going on when you do this.")
"""
print("Read on to understand what is going on when you do this.")
"""
Es muy probable que hayas visto esta sintaxis en varios programas Python; Python utiliza un nombre especial llamado "__main__" y lo establece en un identificador llamado __name__ si el archivo Python que se está ejecutando es el programa principal.
Si decidimos importar el módulo que aparece en la captura de pantalla en otro módulo (archivo Python) y ejecutar ese archivo, la verdad de la expresión en nuestro código será falsa. Esto se debe a que cuando importamos de otro módulo, el identificador __name__ se establece con el nombre del módulo (archivo Python).
#19 El método 'setdefault
import pprint
text = "It's the first of April. It's still cold in the UK. But I'm going to the museum so it should be a wonderful day"
counts = {}
for word in text.split():
counts.setdefault(word, 0)
counts[word] += 1
pprint.pprint(counts)
"""
{'April.': 1,
'But': 1,
"I'm": 1,
"It's": 2,
'UK.': 1,
'a': 1,
'be': 1,
'cold': 1,
'day': 1,
'first': 1,
'going': 1,
'in': 1,
'it': 1,
'museum': 1,
'of': 1,
'should': 1,
'so': 1,
'still': 1,
'the': 3,
'to': 1,
'wonderful': 1}
"
Puede que quieras establecer un valor para varias claves de un diccionario. Por ejemplo, cuando rastreas el recuento de palabras en un corpus. La forma habitual de hacerlo es la siguiente:
- Comprueba si la clave existe en el diccionario
- Si es así, incrementa el valor en 1.
- Si no lo hace, añádelo y fija el valor en 1.
Así es como se ve en código:
counts = {}
for word in text.split():
if word in counts:
counts[word] += 1
else:
counts[word] = 1
Una forma más concisa de hacerlo es utilizar el método setdefault() en tu objeto diccionario.
El primer argumento que se pasa al método es la clave que queremos comprobar. El segundo argumento que se pasa es el valor al que hay que asignar la clave si ésta no existe ya en el diccionario; si la clave existe, el método devolverá el valor de la clave. Por tanto, no se modificaría.
#20 Regex coincidentes
import re
number = re.compile(r"(0?)(\+44)?\d(10)")
num_1 = number.search("My number is +447999999999")
num_2 = number.search("My number is 07999999999")
print(num_1.group())
print(num_2.group())
"""
'+447999999999'
'07999999999'
"""
Las expresiones regulares te permiten especificar un patrón de texto para buscarlo; La mayoría de la gente sabe que podemos buscar cosas utilizando CTRL + F (Windows), pero si no sabes exactamente lo que estás buscando, ¿cómo podrías encontrarlo? La respuesta es buscar patrones.
Por ejemplo, los números del Reino Unido siguen un patrón similar: tendrán un cero al principio más diez números o +44 en lugar de cero y diez números; el segundo caso indica que está en su formato internacional.
Las expresiones regulares ahorran mucho tiempo. Si tuviéramos que codificar reglas para capturar las instancias de nuestra imagen en lugar de regex, podría llevarnos hasta más de 10 líneas de código.
Aprender cómo funcionan las expresiones regulares es vital aunque no escribas código. La mayoría de los editores de texto y procesadores de texto modernos te permiten utilizar expresiones regulares para buscar y sustituir características.
#21 Tubo Regex
import re
heros = re.compile(r"Super(man|woman|human)")
h1 = heros.search("This will find Superman")
h2 = heros.search("This will find Superwoman")
h3 = heros.search("This will find Superhuman")
print(h1.group())
print(h2.group())
print(h3.group())
"""
Superman
Superwoman
Superhuman
"""
Las expresiones regulares tienen un carácter especial llamado tubería(|) que te permite hacer coincidir una de muchas expresiones, y se pueden utilizar en cualquier lugar. Esto es muy útil cuando tienes varios patrones similares.
Por ejemplo, "Superman", "Superwoman" y "Superhumano" tienen el mismo prefijo. Así, podrías aprovechar la tubería para conservar la parte del patrón que es recurrente y cambiar las partes que necesitas que sean diferentes. Una vez más, te ahorramos un tiempo precioso.
Cuidado con el truco: si todas las expresiones que quieres hacer coincidir aparecen en el mismo texto, se devolverá la primera aparición del texto con el que quieras hacer coincidir, es decir, "Un texto de ejemplo que contenga Superwoman, Superman, Superhumano" devolvería Superwoman.
#22 El parámetro 'sep' de la función de impresión
day = "04"
month = "10"
year = "2022"
print(day, month, year)
print(day, month, year, sep = "")
print(day, month, year, sep = ".")
"""
04 10 2022
04/10/2022
04.10.2022
"""
El número de programadores de Python que desconocen todas las capacidades de la función print() asusta; si "Hola Mundo" fue tu primer programa, la función print( ) fue probablemente una de las primeras funciones incorporadas que cubriste cuando aprendiste Python. Utilizamos print() para mostrar mensajes formateados en la pantalla, pero hay mucho más en la función print().
En el código anterior, hemos mostrado diferentes formas de mostrar nuestro mensaje formateado. El parámetro sep es un argumento opcional de la función print( ) que nos permite especificar cómo deben separarse los objetos si incluimos más de uno.
El valor predeterminado es separarlos con un espacio, pero hemos cambiado esta funcionalidad con nuestras sentencias print: una en la que sep se establece en "" y otra en la que sep se establece en ".".
#23 Funciones lambda
def square(num:int) -> int:
return num ** 2
print(f"Function call: {square(4)}")
"""
Function call: 16
"""
square_lambda = lambda x: x**2
print(f"Lambda function: {square_lambda(4)}")
"""
Lambda functional: 16
"""
Las funciones lambda te llevan a las cosas de nivel más intermedio-avanzado que puedes hacer con Python - aprende Python Intermedio con este curso. Parecen complicados a primera vista, pero son bastante sencillos.
En nuestro código de ejemplo, sólo hemos utilizado un argumento, pero podríamos haber utilizado varios si hubiéramos querido:
square = lambda a, b: a ** b
print(f"Lambda function: {square(4, 2)}")
"""
16
"""
En esencia, la palabra clave lambda nos permite crear pequeñas funciones anónimas restringidas en una sola línea. Se comportan como una función normal declarada con la palabra clave def, salvo que estas funciones no tienen nombre.
#24 El método "swapcase
string = "SoMe RaNDoM sTriNg"
print(string.swapcase())
"""
sOmE rAndOm StRInG
"""
El método swapcase( ) se aplica a un objeto cadena para permitirnos cambiar las mayúsculas por minúsculas y viceversa en una sola línea de código. No hay muchos casos de uso del método swapcase(), pero es bueno saberlo.
#25 El método 'isalnum
password = "ABCabc123"
print(password.isalnum())
"""
True
"""
Supongamos que estamos creando un programa que requiere que los usuarios introduzcan una contraseña, pero ésta debe tener una combinación de números y letras. Podemos hacerlo en una línea de código llamando a isalnum() sobre la instancia de cadena.
El método comprueba si todos los caracteres forman parte del alfabeto (A-Za-z) y numéricos (0-9). Un espacio o un símbolo (!#%$&? etc.) devolverá Falso.
#26 Tratamiento de excepciones
def get_ration(x:int, y:int) -> int:
try:
ratio = x/y
except: ZeroDivisionError:
y = y + 1
ratio = x/y
return ratio
print(get_ratio(x=400, y=0))
"""
400.0
"""
Los programas Python terminan cuando encuentran un error.
A veces, no queremos este comportamiento, como cuando tenemos a un usuario final interactuando con nuestro código. ¿Tan malo sería que nuestro código terminara prematuramente en un caso así?
Hay algunas formas de pensar sobre cómo tratar el caso excepcional. La mayoría de los programadores de Python suelen adoptar la idea de que es más fácil pedir perdón que obtener permiso. Esto significa que prefieren atrapar un error planteado proporcionando un contexto circundante que sea capaz de manejar una excepción. La idea que subyace a este pensamiento es que no tiene sentido perder el tiempo intentando protegerse contra todos los diversos casos excepcionales.
Pero esto sólo es válido cuando existe un mecanismo para afrontar un problema después de que se produzca.
#27 Identificar las diferencias en las listas
list_1 = [1, 3, 5, 7, 8]
list_2 = [1, 2, 3, 4, 5, 6, 7, 8, 9]
solution_1 = list(set(list_2) - set(list_1))
solution_2 = list(set(list_1) ^ set(list_2))
solution_3 = list(set(list_1).symmetric_difference(set(list_2)))
print(f"Solution 1: {solution_1}")
print(f"Solution 2: {solution_2}")
print(f"Solution 3: {solution_3}")
"""
Solution 1: [9, 2, 4, 6]
Solution 2: [2, 4, 6, 9]
Solution 3: [2, 4, 6, 9]
"""
Aquí tienes tres métodos diferentes para comparar la diferencia entre dos listas en Python.
Nota: A menos que sepas a ciencia cierta que la lista_1 es un subconjunto de la lista_2, entonces la solución 1 no es igual que las otras dos soluciones.
#28 Args & Kwargs
def some_function(*args, **kwargs):
print(f"Args: {args}")
print(f"Kwargs: {kwargs}")
some_function(1, 2, 3, a=4, b=5, c=6)
"""
Args: (1, 2, 3)
Kwargs: {'a': 4, 'b': 5, 'c': 6}
"""
Utilizamos *args y **kwargs como parámetros de una función cuando desconocemos el número de variables que debe esperar nuestra función.
El parámetro *args nos permite pasar un número variable de parámetros a una función cuando ésta no tiene palabras clave (es decir, los parámetros que pasamos no requieren un nombre asociado). Por otro lado, el parámetro **kwargs nos permite pasar un número arbitrario de parámetros con palabras clave a una función.
En realidad, las palabras *args y **kwargs no son tan mágicas: la verdadera magia está en los asteriscos (*). Esto significa que podríamos haber utilizado cualquier palabra después de los asteriscos, pero el uso de args y kwargs es una práctica común, y se impone entre los desarrolladores de Python.
#29 La elipsis
print(...)
"""
Ellipsis
"""
def some_function():
...
# Alternative solution
def another_function():
pass
La elipsis es un objeto de Python que se puede llamar proporcionando una secuencia de tres puntos (...) o llamando al propio objeto (elipsis).
Su uso más notable es para acceder y trocear matrices multidimensionales en NumPy, por ejemplo:
import numpy as np
arr = np.array([[2,3], [1,2], [9,8]])
print(arr[...,0])
"""
[2 1 9]
"""
print(arr[...])
"""
[[2 3]
[1 2]
[9 8]]
"""
Pero otro uso de la elipsis es como marcador de posición en una función no implementada.
Esto significa que podrías pasar Ellipsis, ..., o pasar, y todas seguirían siendo válidas.
#30 Comprensión de listas
even_numbers = [x for x in range(10) if x % 2 == 0 and x != 0]
print(even_numbers)
"""
[2, 4, 6, 8]
"""
Nuestro último truco de Python son las comprensiones de listas, una forma elegante de crear una lista a partir de otra secuencia. Te permiten realizar lógicas y filtrados sofisticados, como hemos hecho en el código anterior.
Hay otras formas de conseguir el mismo objetivo; por ejemplo, podríamos haber utilizado una función lambda como la siguiente:
even_numbers = list(filter(lambda x: x % 2 ==0 and x != 0, range(10)))
print(even_numbers)
"""
[0, 2, 4, 6, 8]
"""
Pero varios Pythonistas argumentarían que esta solución es mucho menos legible que la comprensión de listas.
Consulta este tutorial para saber más sobre las comprensiones de listas en Python.
Los mejores cursos de Python
Course
Writing Functions in Python
Course
Writing Efficient Python Code
blog
Las 23 mejores preguntas y respuestas de entrevistas sobre Python
blog
¿Para qué se utiliza Python? 7 usos reales de Python
blog
Cómo aprender Python desde cero en 2024: Guía del experto
tutorial
21 herramientas esenciales de Python
tutorial
Tutorial y Ejemplos de Funciones y Métodos de Listas en Python
tutorial