8 truques em Python usados ​​por programadores experientes

imagem



Aqui estão oito truques bacanas de Python que eu tenho certeza que você ainda não viu. Aplique esses truques ao seu código Python para torná-lo mais conciso e com melhor desempenho!



1. Classificando objetos por várias chaves



Suponha que desejemos classificar a seguinte lista de dicionários:



people = [
{ 'name': 'John', "age": 64 },
{ 'name': 'Janet', "age": 34 },
{ 'name': 'Ed', "age": 24 },
{ 'name': 'Sara', "age": 64 },
{ 'name': 'John', "age": 32 },
{ 'name': 'Jane', "age": 34 },
{ 'name': 'John', "age": 99 },
]


Mas não queremos apenas classificá-los por nome ou idade, queremos classificá-los pelos dois campos. No SQL, será uma consulta como esta:



SELECT * FROM people ORDER by name, age


Na verdade, existe uma solução muito simples para esse problema, graças à garantia do Python de que as funções de classificação fornecem persistência de classificação . Isso significa que os elementos comparados mantêm sua ordem original.



Para conseguir a classificação por nome e idade, podemos fazer o seguinte:



import operator
people.sort(key=operator.itemgetter('age'))
people.sort(key=operator.itemgetter('name'))


Observe como mudei a ordem. Primeiro, ordenamos por idade e depois por nome. Usando operator.itemgetter(), obtemos os campos de idade e nome de cada dicionário na lista.



Isso nos dá o resultado que desejávamos:



[
 {'name': 'Ed',   'age': 24},
 {'name': 'Jane', 'age': 34},
 {'name': 'Janet','age': 34},
 {'name': 'John', 'age': 32},
 {'name': 'John', 'age': 64},
 {'name': 'John', 'age': 99},
 {'name': 'Sara', 'age': 64}
]


Os nomes são classificados primeiro, a idade é classificada se o nome corresponder. Assim, todos os Johns são agrupados por idade.



Fonte de inspiração - pergunta do StackOverflow .



2. Inclusão de lista (gerador de lista)



As inclusões de lista podem substituir os loops feios usados ​​para preencher a lista. Sintaxe básica para inclusões de lista:



[ expression for item in list if conditional ]


Um exemplo muito simples para preencher uma lista com uma sequência de números:



mylist = [i for i in range(10)]
print(mylist)
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]


E como você pode usar uma expressão, também pode fazer algumas contas:



squares = [x**2 for x in range(10)]
print(squares)
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]


Ou mesmo chame uma função externa:



def some_function(a):
    return (a + 5) / 2
    
my_formula = [some_function(i) for i in range(10)]
print(my_formula)
# [2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 5.5, 6.0, 6.5, 7.0]


E, finalmente, você pode usar o "se" para filtrar a lista. Nesse caso, armazenamos apenas os valores que são divisíveis por 2:



filtered = [i for i in range(20) if i%2==0]
print(filtered)
# [0, 2, 4, 6, 8, 10, 12, 14, 16, 18]


3. Verifique o uso de memória dos seus objetos



Com sys.getsizeof (), você pode verificar o uso da memória de um objeto:



import sys

mylist = range(0, 10000)
print(sys.getsizeof(mylist))
# 48


Uau ... espere ... por que essa lista enorme pesa apenas 48 bytes?

Isso ocorre porque a função range retorna uma classe que se comporta apenas como uma lista. Um intervalo consome muito menos memória que uma lista real de números.

Você pode ver por si mesmo usando inclusões de lista para criar uma lista real de números do mesmo intervalo:



import sys

myreallist = [x for x in range(0, 10000)]
print(sys.getsizeof(myreallist))
# 87632


Então, depois de brincar sys.getsizeof(), você pode aprender mais sobre Python e seu uso de memória.



4. Classes de dados



A partir da versão 3.7, o Python oferece classes de dados. Há várias vantagens sobre classes regulares ou outras alternativas, como retornar vários valores ou dicionários:



  • classe de dados requer quantidade mínima de código
  • você pode comparar classes de dados porque existe __eq__
  • você pode derivar facilmente uma classe de dados para depuração, porque há __repr__
  • as classes de dados requerem uma dica de tipo, o que reduz a chance de erros


Aqui está um exemplo de uma classe de dados em operação:



from dataclasses import dataclass

@dataclass
class Card:
    rank: str
    suit: str
    
card = Card("Q", "hearts")

print(card == card)
# True

print(card.rank)
# 'Q'

print(card)
Card(rank='Q', suit='hearts')


Um guia detalhado pode ser encontrado aqui .



5. Pacote atrai



Em vez de classes de dados, você pode usar attrs . Há duas razões para escolher attrs:



  • Você está usando uma versão do Python anterior à 3.7
  • Você quer mais opções


O pacote attrssuporta todas as principais versões do Python, incluindo o CPython 2.7 e o PyPy. Alguns dos atributos adicionais oferecidos attrsem classes de dados regulares são validadores e conversores. Vamos dar uma olhada em alguns exemplos de código:



@attrs
class Person(object):
    name = attrib(default='John')
    surname = attrib(default='Doe')
    age = attrib(init=False)
    
p = Person()
print(p)
p = Person('Bill', 'Gates')
p.age = 60
print(p)

# Output: 
#   Person(name='John', surname='Doe', age=NOTHING)
#   Person(name='Bill', surname='Gates', age=60)


Os autores attrsrealmente trabalharam no PEP, que introduziu classes de dados. As classes de dados são intencionalmente mantidas mais simples (mais fáceis de entender), enquanto o attrs oferece um conjunto completo de funções que você pode precisar!



Mais exemplos podem ser encontrados na página de exemplos attrs .



6. Combinando dicionários (Python 3.5+)



Desde o Python 3.5, é mais fácil combinar dicionários:



dict1 = { 'a': 1, 'b': 2 }
dict2 = { 'b': 3, 'c': 4 }
merged = { **dict1, **dict2 }
print (merged)
# {'a': 1, 'b': 3, 'c': 4}


Se houver teclas sobrepostas, as teclas do primeiro dicionário serão substituídas.



No Python 3.9, combinar dicionários é ainda mais limpo. A mesclagem acima no Python 3.9 pode ser reescrita como:



merged = dict1 | dict2


7. Procure o significado mais comum



Para encontrar o valor mais comum em uma lista ou sequência:



test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
print(max(set(test), key = test.count))
# 4


Você entende por que isso funciona? Tente descobrir por si mesmo antes de ler mais.



Você até tentou, não é? Eu vou te dizer assim mesmo:



  • max()retornará o valor mais alto da lista. O argumento keyusa uma única função de argumento para personalizar a ordem de classificação, neste caso test.count. A função é aplicada a cada elemento do iterável.
  • test.count- função de lista embutida. É preciso um argumento e contará o número de ocorrências para esse argumento. Portanto, ele test.count(1)retornará 2 e test.count(4)retornará 4.
  • set(test) retorna todos os valores exclusivos do teste, então {1, 2, 3, 4}


Portanto, nesta única linha de código, aceitamos todos os valores exclusivos para um teste {1, 2, 3, 4}. Em seguida, maxaplicará uma função a eles list.counte retornará o valor máximo.



E não - eu não inventei essa frase.



Atualização: Vários comentaristas observaram, com razão, que há uma maneira muito mais eficiente de fazer isso:



from collections import Counter
Counter(test).most_common(1)
# [4: 4]


8. Retorne vários valores



As funções no Python podem retornar mais de uma variável sem um dicionário, lista ou classe. Funciona assim:



def get_user(id):
    # fetch user from database
    # ....
    return name, birthdate

name, birthdate = get_user(4)


Isso é normal para um número limitado de valores de retorno. Mas qualquer coisa acima de 3 valores deve ser colocada na classe (data).



imagem



Descubra os detalhes de como obter uma profissão de alto nível do zero ou subir de nível em habilidades e salário fazendo os cursos on-line pagos do SkillFactory:











All Articles