Em Python
isso aí é uma linha
Quem sou eu
Tyrone Damasceno
Apaixonado por Python e membro do Grupy-RN
Desenvolvedor back-end na Evolux
Bacharel em TI pela UFRN
Burger lover

@tyronedamasceno
O que vamos ver hoje?
import base64, sys; base64.decode(open(sys.argv[1], "rb"), open(sys.argv[2], "wb"))
import sys,os,re,fileinput;a=[i[2] for i in os.walk('.') if i[2]] [0];[
sys.stdout.write(re.sub('at','op',j)
for j in fileinput.input(a,inplace=1)]
print (
'\n'.join("%i Byte = %i Bit = largest number: %i" % (j, j*8, 256**j-1)
for j in (1 << i for i in xrange(8)))
)
f = lambda x: [
[y for j, y in enumerate(set(x)) if (i >> j) & 1] for i in range(2**len(set(x)))]
Sério, o que veremos hoje?
- Iteradores
- List Comprehensions
- Geradores
- Expressões Geradoras
Como, quando e por quê usar!
Iteradores
Tudo aquilo em que se pode iterar, ou seja, percorrer com um laço for.
>>> numeros = [1, 2, 3, 4, 5, 6, 7]
>>> for n in numeros:
... if n % 2 == 0:
... print(n)
...
2
4
6
>>>
List Comprehensions
- É uma forma de construir novos iteráveis.
- Ou de transformar iteráveis
- Não é pra economizar linhas
List Comprehensions
>>> numeros = [1, 2, 3, 4, 5, 6, 7]
>>> pares = []
>>> for n in numeros:
... if n % 2 == 0:
... pares.append(n)
...
>>> print(pares)
[2, 4, 6]
Criando uma lista de pares
List Comprehensions
>>> numeros = [1, 2, 3, 4, 5, 6, 7]
>>> pares = [n for n in numeros if n % 2 == 0]
>>> print(pares)
[2, 4, 6]
Criando uma lista de pares
[item for item in iteravel if item % 2 == 0]
List Comprehensions
Criando listas de listas
>>> lista_de_listas = [
... [x + y for x in range(3)]
... for y in range(3)
... ]
>>> lista_de_listas
[[0, 1, 2], [1, 2, 3], [2, 3, 4]]
>>>
>>> type(lista_de_listas)
<class 'list'>
>>> type(lista_de_listas[0])
<class 'list'>
List Comprehensions
Modificando uma lista
>>> galera_massa = ['Tyrone', 'GeRaLdO', 'ALLYTHY', 'Sedir']
>>> galera_massa = [nome.lower() for nome in galera_massa]
>>> galera_massa
['tyrone', 'geraldo', 'allythy', 'sedir']
List Comprehensions
"Readability counts."
numeros = [1, 2, 3, 4, 5, 6, 7]
lista_bolada = [(n**2/6) for n in numeros if is_prime(n) else 44]
"Readability counts."
List Comprehensions
"Readability counts."
numeros = [1, 2, 3, 4, 5, 6, 7]
lista_bolada = [
(n**2/6)
for n in numeros
if is_prime(n)
else 44
]
"Readability counts."
Set e dict comprehensions
>>> my_set = {
... x**2
... for x in range(-2, 3)
...}
>>> my_set
{0, 1, 4}
>>> type(my_set)
<class 'set'>
>>> my_dict = {
... x: x**2
... for x in range(-2, 3)
... }
>>> my_dict
{-2: 4, -1: 1, 0: 0, 1: 1, 2: 4}
>>> type(my_dict)
<class 'dict'>
Set comprehension
Dict comprehension
Geradores
- Criar um iterador de forma lazy
- Geração dos valores sob demanda
- Pausar a criação do iterável
- Só podem ser usados uma vez
Expressões geradoras
- Por que não "generator comprehension"?
- Servem para criar geradores
- Use quando precisa iterar sobre uma lista uma única vez
- Basicamente troca os colchetes por parênteses
>>> a = [x+7 for x in range(4)]
>>> a
[7, 8, 9, 10]
>>> type(a)
<class 'list'>
>>> a = (x+7 for x in range(4))
>>> a
<generator object <genexpr> at 0x1b>
>>> type(a)
<class 'generator'>
Geradores
- Não sabem quantos valores possuem, e isso permite criar geradores infinitos
>>> gerador_gigante = (x for x in range(1000000000000))
>>> len(gerador_gigante)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
Geradores
- Mas você pode criar uma lista, ou um set com um gerador, por exemplo
>>> fibonelson = [1, 1, 2, 3, 5, 8, 11, 19]
>>> fib_quadrado = (fib**2 for fib in fibonelson)
>>> type(fib_quadrado)
<class 'generator'>
>>> lista_fibs_quadrados = list(fib_quadrado)
>>> lista_fibs_quadrados
[1, 1, 4, 9, 25, 64, 121, 361]
Geradores
- Sempre lembrando que o gerador vai iterar uma unica vez
>>> fibonelson = [1, 1, 2, 3, 5, 8, 11, 19]
>>> fib_quadrado = (fib**2 for fib in fibonelson)
>>> lista_fibs_quadrados = list(fib_quadrado)
>>> lista_fibs_quadrados_2 = list(fib_quadrado)
>>> lista_fibs_quadrados
[1, 1, 4, 9, 25, 64, 121, 361]
>>> lista_fibs_quadrados_2
[]
>>> fib_quadrado
<generator object <genexpr> at 0x102bfcc78>
>>> next(fib_quadrado)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Geradores
- O método next é o responsável por iterar, e é ele que nos permite chamar um gerador de lazy
>>> gerador_de_pares = (x*2 for x in range(10))
>>> next(gerador_de_pares)
0
>>> next(gerador_de_pares)
2
>>> next(gerador_de_pares)
4
>>> # Algumas chamadas...
>>> next(gerador_de_pares)
18
>>> next(gerador_de_pares)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Geradores
- O método next é o responsável por iterar, e é ele que nos permite chamar um gerador de lazy
>>> gerador_de_pares = (x*2 for x in range(10))
>>> next(gerador_de_pares)
0
>>> next(gerador_de_pares)
2
>>> next(gerador_de_pares)
4
>>> # Algumas chamadas...
>>> next(gerador_de_pares)
18
>>> next(gerador_de_pares)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
Geradores
- Podemos chamar funções diretamente sobre geradores ou expressões geradoras
>>> numberos = [1, 2, 3, 4, 5]
>>> numeros = [1, 2, 3, 4, 5]
>>> quadrados = (x**2 for x in numbs)
>>> sum(quadrados)
55
>>> sum(quadrados)
0
>>> sum((x**2 for x in numbs))
55
>>> sum(x**2 for x in numbs)
55
Vou sair metendo comprehension em tudo?
- Não
- Não
- Talvez
Quando não usar
- Quando não é necessário
>>> [print(x) for x in range(5)]
0
1
2
3
4
[None, None, None, None, None]
Quando não usar
- Quando afeta a legibilidade
print (
'\n'.join("%i Byte = %i Bit = largest number: %i" % (j, j*8, 256**j-1)
for j in (1 << i for i in xrange(8)))
)
Quando não usar
- Quando gastar mais linhas que usando o for
>>> frutas = ['Abacaxi', 'Uva', 'Laranja', 'Mangaba']
>>> nota_do_suco = [7, 8.3, 9, 10]
>>> fruta_e_nota = {}
>>> for fruta, nota in zip(frutas, nota_do_suco):
... fruta_e_nota[fruta] = nota
...
>>> fruta_e_nota_comp = {
... fruta: nota
... for fruta, nota in zip(frutas, nota_do_suco)
... }
>>> fruta_e_nota == fruta_e_nota_comp
True
Quando não usar
- Lembrem que estamos falando de Python, sempre dá pra fazer em uma linha!
>>> fruta_e_nota = dict(zip(frutas, nota_do_suco))
>>> fruta_e_nota
{'Abacaxi': 7, 'Uva': 8.3, 'Laranja': 9, 'Mangaba': 10}
Obrigado!
Estou disponível em
@tyronedamasceno no telegram, instagram, github...

Em Python isso aí é uma linha
By Tyrone Damasceno
Em Python isso aí é uma linha
- 91