Que o Python é uma linguagem fantástica e simples de trabalhar, todo mundo já sabe. Mas ele pode ser ainda mais legal =D.
Abaixo vou mostrar algumas dicas simples, e que deixarão seu código bem mais conciso e otimizado. Bora ver =).
Evite loops aninhados com função product()
Essa descobri recentemente, e curti demais. Trata-se de uma função built-in do módulo itertools.
As vezes precisamos criar loops aninhados, o que pode deixar nosso código mais lento e difícil de ser lido, e essa função vem para nos ajudar nisso.
Segue um exemplo simples:
def nested_loop():
start_time = time.perf_counter()
for a in list_a:
for b in list_b:
for c in list_c:
v = a + b + c
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f">>> Nested loops execution time: {execution_time:.2f}")
Mesmo código, mas agora usando a função product():
def product_function():
start_time = time.perf_counter()
from itertools import product
for a, b, c in product(list_a, list_b, list_c):
v = a + b + c
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f">>> Product function execution time: {execution_time:.2f}")
Aqui o código completo com teste de performance. Essa performance aumenta conforme a complexidade do que seu código aumenta:
import numpy as np
import time
list_a = np.random.randint(1000, size=300)
list_b = np.random.randint(1000, size=300)
list_c = np.random.randint(1000, size=300)
def nested_loop():
start_time = time.perf_counter()
for a in list_a:
for b in list_b:
for c in list_c:
v = a + b + c
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f">>> Nested loops execution time: {execution_time:.2f}")
def product_function():
start_time = time.perf_counter()
from itertools import product
for a, b, c in product(list_a, list_b, list_c):
v = a + b + c
end_time = time.perf_counter()
execution_time = end_time - start_time
print(f">>> Product function execution time: {execution_time:.2f}")
if __name__ == "__main__":
nested_loop()
product_function()
Assignment Expressions
Essa é uma forma bem legal de você atribuir um valor à variável enquanto utiliza-o. Da uma olhada:
O código abaixo est´á sem o uso de expressão de atribuição
var1 = input("Valor 1: ")
var2 = input("Valor 2: ")
if int(var1) == int(var2):
print("Igual")
else:
print("Diferente")
print(f"Valor 1: {var1}, Valor 2: {var2}")
E agora utilizando expressão de atribuição:
if int(var1 := input("Valor 1: ")) == int(var2 := input("Valor 2: ")):
print("Igual")
else:
print("Diferente")
print(f"Valor 1: {var1}, Valor 2: {var2}")
Legal né… e vc pode usar de outras formas… por exemplo, em um loop:
while (texto := input("Digite um texto: ")) != "sair":
print("Texto digitado: ", texto)
Operator condicional ternário, ou simplesmente… if ternário
Para resolver condições simples que envolvam apenas 2 saídas, mais que isso não recomendo o uso de if ternários, pois podem deixar seu código muito difícil de entender:
A sintax é simples:
min = a if a < b else b
Aplicando no if do exemplo anterior, ficaria assim:
print("Igual" if int(var1 := input("Valor 1: ")) == int(var2 := input("Valor 2: ")) else "Diferente")
print(f"Valor 1: {var1}, Valor 2: {var2}")
Funções lambda para operações simples
Esse é uma das coisas mais legais do python. A criação de funções anônimas para operações simples. O legal que elas não precisam ser tão anônimas assim, já que conseguimos atribuir uma função lambda a uma variável, e usar essa variável como se fosse uma função definida. Assim:
soma = lambda x,y: x+y
print(soma(1,2))
Outro exemplo legal… uma função para retornar os números da sequência fibonacci
def fib(x):
if x<=1:
return x
else:
return fib(x-1) + fib(x-2)
Com o uso de lambda:
fib = lambda x: x if x <= 1 else fib(x - 1) + fib(x - 2)
List Comprehensions
Este é sem dúvidas uma das coisas mais legais do Python, a compreensão de listas. É uma forma bem simples e prática de trabalhar com listas.
A sintaxe é simples:
lista_b = [item for item in lista_a [condições] ]
Abaixo um exemplo utilizando list comprehensions com a função lambda que criamos log acima:
fib = lambda x: x if x <= 1 else fib(x - 1) + fib(x - 2)
lista = [fib(i) for i in range(1,11)]
print(lista)
O que fizemos aqui foi simplesmente criar uma lista com 10 números da sequência fibonacci… legal né?! mas da pra fazer muito mais… olha esse outro exemplo:
# Filtrando somente frutas que comecem
# com a letra M da lista 'frutas'
frutas = ['Banana', 'Maça', 'Pera', 'Abacaxi', 'Uva', 'Melão', 'Melancia', 'Mamão', 'Jaca']
fm = [fruta for fruta in frutas if fruta.startswith('M')]
print(frutas)
print(fm)
Funções de ordem superior
O python possui algumas funções de ordem superior que são verdadeiras jóias quando trabalhamos com dados em larga escala.
Uma função de ordem superior são aquelas funções que recebem outras funções como parâmetros e retornam funções e/ou iterators.
Abaixo um exemplo utilizando a função map():
frutas = ['Banana', 'Maça', 'Pera', 'Abacaxi', 'Uva', 'Melão', 'Melancia', 'Mamão', 'Jaca']
frutas = map(str.upper, frutas)
print(frutas)
# <map object at 0x7f881000cfa0>
print(list(frutas))
#['BANANA', 'MAÇA', 'PERA', 'ABACAXI', 'UVA', 'MELÃO', 'MELANCIA', 'MAMÃO', 'JACA']
Próximo exemplo, aproveitando a lista de frutas do exemplo anterior, vamos ver a função reduce():
r = reduce(lambda x, y: x if len(x) > len(y) else y, frutas)
print(f"{r} é a maior palavra da lista")
# MELANCIA é a maior palavra da lista
Legal né?! 😀
Se você ainda não viu o post sobre Multiprocessing com python, da uma olhada nesse link abaixo:
https://variavelconstante.com.br/2022/04/17/multiprocessing-em-python-extraindo-o-maximo-que-a-sua-maquina-pode-entregar/
Python é fantástico, e isso que eu nem falei sobre generators… mas isso é tema para um próximo post 😀
Abraço!
Fonte: https://medium.com/techtofreedom/9-fabulous-python-tricks-that-make-your-code-more-elegant-bf01a6294908