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
attrs
suporta todas as principais versões do Python, incluindo o CPython 2.7 e o PyPy. Alguns dos atributos adicionais oferecidos attrs
em 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
attrs
realmente 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 argumentokey
usa 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, eletest.count(1)
retornará 2 etest.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, max
aplicará uma função a eles list.count
e 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).
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:
- Machine Learning (12 )
- Data Science (12 )
- (9 )
- «Python -» (9 )