Mostrando postagens com marcador Python. Mostrar todas as postagens
Mostrando postagens com marcador Python. Mostrar todas as postagens

12 de mar. de 2012

bpython, um belo console de Python

Um dos pontos fortes da linguagem Python, é a possibilidade de prototipar rapidamente atráves do seu poderoso console.

Para quem sentia necessidade de maior agilidade usando o console, o IPython, trouxe várias features, como o uso de instrospecção, que permite o auto-complete de métodos e atributos e acesso as Docstrings, dentre outras características que ajudam os desenvolvedores.

Eu descobri essa semana outro interpretador, o bpython. Com features parecidas as do IPython, mas um layout mais próximo do console original, ele já poderia substituir o IPython sem problemas. Mas algumas features são bem chamativas, dentre elas destacaria, o suporte ao compartilhamento de código via bpaste e a possibilidade de salvar o código em arquivo.

fonte: http://bpython-interpreter.org




Para mais informações, acesse a documentação do bpython.

11 de mar. de 2012

List Comprehensions em Python

List comprehensions, em ciência da computação, é um construtor de listas que se baseia em outras listas pré-existentes.

Esse conceito não é novo e data dos anos 60's. Mas o termo comprehension foi usado pela primeira vez na linguagem NPL.

E as List Comprehension tem como origem as representação do conjuntos da matemática:

{x ∈ N | 0 < x < 7}
Lê-se: x pertence ao conjunto dos Naturais, tal que 0 é menor que x e x menor que 7. O que restringiria esse conjunto a {1, 2, 3, 4, 5, 6}.

Em Python, uma List comprehension tem a seguinte sintaxe:

[x * 2 for x in lista]
Nesse exemplo abaixo, multiplicamos os itens da lista por 2, atribuimos à variável nova_lista:

>>> lista = [1, 2, 3, 4, 5]  
>>> nova_lista = [x * 2 for x in lista]  
>>> nova_lista  
[2, 4, 6, 8, 10]  
Sendo que o 'x * 2' é executado em cada item da lista. Um código mais limpo  e intuitivo do que uma versão usando a builtin function map.

>>> def vezes_2(n):
...     return n * 2
...     
... 
>>> map(vezes_2, range(6))
[0, 2, 4, 6, 8, 10]
Poderiamos fazer essa operação com uma lambda function.

>>> map(lambda x: x * 2, range(6))
[0, 2, 4, 6, 8, 10]

Um código análogo sem List comprehension:

>>> lista = [1, 2, 3, 4, 5]  
>>> nova_lista = []  
>>> for x in lista:  
...   nova_lista.append(x * 2)  
...    
...  
>>>  
>>> nova_lista  
[2, 4, 6, 8, 10]  
Dentro das  List comprehensions ainda se pode usar condicionais, para filtrar elementos na criação das novas listas.

>>> frase = ['o', 'rato', 'roeu', 'a', 'roupa', 'do', 'rei', 'de', 'roma']
>>> [p for p in frase if p[0] == 'r'] 
['rato', 'roeu', 'roupa', 'rei', 'roma']
Aqui eu verifico se a primeira letra da palavra é 'r'.

Criei um pequeno script para comparar a performance das List comprehensions. Escrevi duas funções, uma usando List comprehensions e outra não, que criam uma lista com os números pares entre 0 e 1000000. Para fazer a comparação usei a biblioteca cProfile.

def foo():  
    l = []  
    for i in range(1000000):  
        if i % 2 == 0:  
            l.append(i)

def foo_listcomp():  
    l = [i for i in range(1000000) if i % 2 == 0]  

cProfile.run('foo()')  
cProfile.run('foo_listcomp()')  
Executando o código.

$ python bench.py  
   500004 function calls in 1.739 seconds  


Ordered by: standard name  

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.009    0.009    1.739    1.739 <string>:1(<module>)
     1    0.936    0.936    1.730    1.730 bench.py:61(foo)
500000    0.769    0.000    0.769    0.000 {method 'append' of 'list'...
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof...
     1    0.025    0.025    0.025    0.025 {range}
  

   4 function calls in 0.165 seconds  

Ordered by: standard name  

ncalls  tottime  percall  cumtime  percall filename:lineno(function)
     1    0.015    0.015    0.165    0.165 :1()
     1    0.125    0.125    0.150    0.150 bench.py:67(foo_listcomp)
     1    0.000    0.000    0.000    0.000 {method 'disable' of '_lsprof...
     1    0.024    0.024    0.024    0.024 {range}  
O código convencional chega a ser 10 vezes mais lento que o código que utiliza List comprehension. 1.739 segundos contra 0.165.

A performance e a simplicidade do código justifica o uso das List comprehensions quando se quer criar listas a partir de listas, sua finalidade semântica. Mas quando a lógica envolvida na geração da nova lista é muito complexa, o seu uso pode diminuir a legibilidade do código drasticamente.

Referências:
Google Style Guide
Documentação Python
The History of Python