Pythonic way of life

22/05/2008 - 14:20 PM

Pythonic Way of life

Exemplo, por favor?
Vejamos um dos exemplos mais simples de programação: Exibir os números pares até 20.

Em C, por exemplo, podemos fazer assim:

int n;
for (n = 0; n <= 20; n++) {
. . . if (n % 2 == 0)
. . . . . printf(”%d “, n);
}

Em Python podemos fazer de forma semelhante, mas há uma alternativa bem mais simples:

print [ x for x in range(21) if  x % 2 == 0 ]

Essa construção sintática se chama “List comprehension“. Traduzindo, a expressão acima, significa:

“Gere uma lista de números de 0 a 20, com a função range(21). Para cada um desses números, verifique se são divisíveis por 2. Se forem, insira-os numa lista”.

O print vai imprimir a lista de números pares, separados por uma vírgula, dessa forma:

[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

É isso. E como diz o Zen of Python, “Simple is better than complex”

Mantendo a retro-compatibilidade

56 pessoas não foram à escola.

  1. Paulino Michelazzo

    Nerdson,

    A questão da redução de linhas em um código tem dois lados. O primeiro que serve para deixar o código “enxuto” para quem está vendo o mesmo e o segundo, que deixa-o de tal forma “complexo” que demora-se muito mais para compreendê-lo.

    Não é feio fazer códigos grandes. Não é feio fazer códigos extensos. O feio mesmo é fazer código sem comentários e daqueles que só “nerdsons” compreendem ;)

    Simple is better than complex when you can read ;)

  2. Daniel Ruoso

    arrramm…

    Brincar de golf é esporte de outra linguagem ;), e é pq eu nem estou jogando ainda… isso é só o jeito natural de fazer ;)

    print join ‘, ‘, grep { $_ % 2 == 0 } 0..20;

    (preciso dizer qual é a linguagem?)

    daniel

  3. Karlisson

    E aqui temos um post que pode gerar um flamewar :)

  4. Daniel Ruoso

    Agora, se é para jogar golf…

    print join’, ‘,grep{~$_&1}0..20

    Alguém se habilita?

  5. André Gondim

    hehhe python surpreende mesmo!!

    Abraços!! ;)

  6. Karlisson

    Caros, não estou dizendo que Python é a melhor linguagem nem que códigos com poucas linhas são melhores. Não foi essa a minha intenção ao escrever o post. A intenção é mostrar algo que PODE SER feito em Python, de forma simples, apresentando o conceito - independente de linguagem - chamado “list comprehension”, que pode fazer muito mais do que listar números pares. O exemplo do post não necessariamente se refere à tirinha. ;)

  7. damnerd

    One-Liner C++ ->
    for(int i=0; i<20; printf(”%d,”, i+=2));

    Mas quem precisa de linguagem de programação? escreve direto na RAM da máquina…

  8. Leandro

    Mais fácil ainda (em Python): print range(0, 21, 2)

  9. FelipeBZ

    Ruby:
    (0..20).each {|n| puts n if n % 2 == 0}

    :D

  10. Felipe Ribeiro

    É mais “simples”, mais “bonito” mas não tem milagre, nessa única linha de python tem também explicitamente todas as intruções que teria em C.

    Tem o for, tem o if e tem o print, não tem mágica nenhuma… :)

  11. Bruno Guedes & Toupeiras - Curso Básico de Expressões Regulares

    Hehehe, programadores Python…

    Adorei essa tira, adoro Python e não sei porque cargas d’água tem gente que se importa tanto em provar que Python não é a maravilha maior do Universo…

    Programming Language is SERIOUS BUSINESS?

  12. Renan Vieira

    Show!

    Cada post sobre Python que leio aqui no NERDSON me dá vontade de voltar a prender Python, parei no básicão.

    :P

  13. Karlisson

    Pronto, com esse comentário do Renan consegui fazer com que o post atingisse seu objetivo.
    Obrigado pela compreensão.

  14. Renan Vieira

    Mission Accomplished.

    :D

  15. ricardo

    ou ainda usando o mm algorito (resto da divisao) em c++…

    for(int n=0; n++<=20;(n%2)?n:printf(”%d “,n));

    claro que o for(int i=0; i<20; printf(”%d,”, i+=2)); é boa ideia, saltar logo de 2 em 2…. hehehe

    qt ao python acho que é mm moda, queria era ver isso feito em ocaml , de certeza que bate as linguagens imperativas neste tipo de problemas hehehehe amanha se tiver paciencia penso nisso…

  16. Renan Vieira

    Ricardo,
    No link da Wikipédia que tem ali no post, tem um exemplo bem parecido com o de Python, de F#, que se não me engano é uma variação do OCaml pra plataforma .NET.

    { for x in 0..100 when x*x > 3 -> 2*x }

    Pena que em C# não o código não fica tão elegante. =/ huahueahuuhe

  17. python anonymous coward

    print range(0, 21, 2)

    Beautiful is better than ugly.

  18. Karlisson

    Desisto.

  19. FelipeBZ

    Ao pessoal que está mostrando os números de 2 em 2 (ex: com a função range do python), e se fosse pra imprimir os pares entre 1 e 20?

    FAILED - MISSION ABORTED!

  20. Thadeu Penna

    for (i=1;i<=20;i++) print (”%d “,i*(1-i&1))

    isto evita um custoso if.

    Fast is beautiful.

  21. Roger Demetrescu

    Fala FelipeBZ…

    print [x for x in range(0, 21, 2) if x]

    ou

    print [x+1 for x in range(1, 21, 2)]

  22. ricardo

    “Ricardo,
    No link da Wikipédia que tem ali no post, tem um exemplo bem parecido com o de Python, de F#, que se não me engano é uma variação do OCaml pra plataforma .NET.

    { for x in 0..100 when x*x > 3 -> 2*x }

    Pena que em C# não o código não fica tão elegante. =/ huahueahuuhe”

    F# é a resposta da micro às linguagens funcionais, sendo o ocaml uma delas. Mas só a ver aí um for explicito é logo má programação funcional, melhor, é usar programação funcional para para programar imperativamente. Um bocado como usar um trator para ir à praia, podemos fazer mas nao foi para isso que foram feitos…

  23. InFog

    Nem sempre uma redução no número de linhas é uma coisa boa. Para quem tiver que dar manutenção no código (às vezes você mesmo) isso pode ser uma bela dor de cabeça. Tudo bem que existem casos e mais casos, mas ter instruções separadas linha a linha podem ajudar o pobre cérebro humano a entender mais facilmente =)

    InFog

  24. Rafael C. de B.

    Nossa como o pessoal gosta de complicar as coisas neh hehehe pior que eh assim na programação, lido todo dia com complicações que outros “programadores” fazem e tento simplificar, e não importa a linguagem, se da pra simplificar e deixar entendível pelos outros “programadores” ai blz.
    Adoro Python, esse post me fez sentir bem e com mais vontade ainda de usar meu tempo livre para aprender e me aprofundar mais na linguagem.

    []’s

  25. Trovalds

    Karl, não se preocupe. A melhor linguagem de programação que existe (pra mim) é a que paga as contas no final do mês (ou no começo).

    Eu comecei a aprender Python, fiquei bem no básico mesmo, mas é uma linguagem que se tivesse algum investimento (ou apoio) de grandes da indústria iria derrubar muita linguagem dita poderosa. A propósito, dê uma olhada nas libs gráficas (GTK se não me engano) para python. Elas fazem maravilhas em interface gráfica com poucas linhas de código.

    E agradeça por até agora não aparecer ninguém do Java dizendo que não existe “tipagem forte” no Python (já que não existe como fazer algo parecido em 1 linha no Java).

    PS: agora que fui prestar atenção direito nos comentários anteriores. Sem comentários a respeito de alguns…

  26. Dimitri Lameri

    Python gerou tanta polemica que fiquei ate com vontade de aprender =P
    []’s

  27. Julia Pedreira

    ah muito bom o post, e a guerrinha de brinde :D

    minha area nao é programação, mas um dia tentei aprender python….mas tbm parei no basiquissimo.
    apesar de ser simples, acaba sendo meio “viajante” pra alguem de fora da area de computação…. eu por exemplo levaria um bom tempo pra compreender essa unica linha de codigo!

  28. Renan Vieira

    Bom, pelo menos o post está tendo bastante comentários.

    Concordo com o amigo Trovalds ali em cima. A melhor é a que paga as contas no final do mês, por isso sou fã do C#… ;P

    Estou retomando meus estudos de Python, alguém tem um bom livro pra indicar?

    Inté!

  29. tiago

    python+pygtk eh a maneira mais simples de se fazer um programa grafico que conheço
    e se usar wxwidgets o negocio fica totalmente portavel
    MAS, nao gosto de programas muito complexos feitos em python, por exemplo o Exaile, tende a ficar lento

  30. Mateus

    for(n=0;n<=20;n=n+2,printf(”%d “,n));

    Essa meus alunos aprenderam na aula C
    :)

  31. Murilo Adriano

    for (int i = 0; i < 21; i += 2) printf(”%d “, i); 37 chars
    print [ x for x in range(21) if x % 2 == 0 ] 31 chars

    Agora compare a velocidade de uma e de outra ;P

  32. Murilo Adriano

    Como eu sei que ninguém ia comparar os tempos de execução, eu comparei:

    murilo@blacksheep:~$ time python -c “print [ x for x in range(21) if x % 2 == 0 ]”
    [0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20]

    real 0m0.017s
    user 0m0.008s
    sys 0m0.008s

    murilo@blacksheep:~$ time ./for
    0 2 4 6 8 10 12 14 16 18 20
    real 0m0.002s
    user 0m0.000s
    sys 0m0.000s

    O de baixo é o for que disse acima compilado com o gnu g++.

  33. Wendel

    Gente, tenham em mente: Golf é divertido, mas não é pra ser levado a sério (ou seja, não tente enfiar o máximo possível de código no mínimo de caracteres, a não ser por diversão).

    Agora, no post em si, a idéia não é usar poucos caracteres, mas sim ser mais claro. Se lembrarem de teoria dos conjuntos, verão que

    print [ x for x in range(21) if x % 2 == 0 ]

    equivale a

    { x pertence a {0 … 20} | x = 0 (mod 2) }

    Quanto ao Perl Golf, minha tacada é:

    print join’, ‘,map$_*2,0..10

    ou melhor ainda:

    $,=’, ‘;print map$_*2,0..10

    Aliás, se alguém quiser jogar esse tipo de golf na internet, seja em Perl, PHP, Python ou Ruby, sugiro o http://codegolf.com/ . Pena que meu score costuma ser o dobro dos piores (sendo que menor = melhor)

  34. the door

    meu professor de sistemas distribuidos disse que tudo depende do Siqueira, as coisas ficam tão complicadas quanto siqueira :P
    se queira, sacou? tah eu sei q foi sem graça =/

  35. PotHix

    Æ!!

    Ainda bem que postaram um de Ruby…heheheh…Eu já estava vindo aqui para postar tambem! =D

    To com vontade de aprender Python tambem…Qualquer hora eu vou pegar para brincar um pouco.

    Há braços

  36. Lucas Castro

    ihhh eu acho que o pessoal entendeu errado kkkkkkkk

    Fazer códigos com menos elementos é uma característica comum de programadores de lingagens dinamicas, mas pq a linguagem dá ferramentas pra que vc faça isso de forma elegante :D

    Além do mais todo mundo sabe que isso não importa, afinal. É apenas uma característica dos programadores ^^

  37. Felipe

    Esses posts envolvendo mais de uma linguagem de programação, mais de um SO, mais um time de futebol, etc, sempre geram disputa… Se você juntar Hitler e Deus num único post, aposto que vai ter alguém para defender Hitler.

  38. Leandro

    E que tal assim:
    select *
    from ( select case when mod(rownum,2) = 0 then rownum
    end numero
    from dual
    connect by rownum < 20
    ) lista
    where lista.numero is not null

    SQL RULA!

  39. Leandro

    Ops, no comentário anterior o operador relacional deveria ser <=, se não ele não vai considerar o 20.

  40. Rudá Porto Filgueiras

    Eu adorei a tira!

    Para quem não foi iniciado ao conceito é bem interessante saber que existe uma forma mais natural, mesmo que não pareça a primeira vista, de gerar uma lista a partir de outra lista.

    Legibilidade conta!

    E para quem quer aprender Python, abrir a mente, eu recomendo o livro Dive Into Python, disponível gratuitamente na Internet.

    No primeiro exemplo ele mostra list compreension, atribuição múltipla, etc. Mas distrincha tudo, linha a linha. E continua assim por todo o livro, vale a pena cada minuto investido lendo os exemplos. ;-)

    Espero ter contribuído.. e sem guerra de linguagens, vamos respeitar as escolhas de cada um.

  41. Homem Aleatorio

    Hum… O que foi isso? Jabá de Python?

    (Legal a tira… Mas como eu não manjo Python, então… Whatever.)

    o/

  42. Humberto Diógenes

    E aí, Karlisson, você imaginou que *uma* inocente linha de Python fosse ser re-escrita de todas as formas diferentes? Até com comparações de performance! Putz…

    Galera, o autor só quis dizer que Python é uma linguagem concisa e bonita, e é mesmo. Pronto! Podem continuar curtindo vossas linguagens e parar com as comparações! :P

  43. Flavio

    for (int n = 0; n <= 20; n=n+2) printf(”%d “, n);

    EM UMA LINHA!!!! =D

  44. Jpunker

    Python, a preguiça da programação! hehehe…, nunca mexi com essa linguagem, mas me surpreendo com o que ela pode fazer, porem a coisa que eu mais odeio no pythonianos são seus exemplos, de ficar mostrando que o intepretador também é uma calculadora!!! Grandes Porcaria hehe… Um dia eu estudo mais afundo Python… =), tambem gosto de facilidades! Pena que não é uma linguagem ainda reconhecida no mercado de trabalho, dificilmente vejo uma empresa trabalhar com python =(

  45. Japa

    código compacto != código simples, não confundam o artigo com o numeral.

  46. Adorilson

    eu quero é saber para onde foi parar a serie o “Ataque do bots assassinos”. Ele já tá sumindo ali da listagem…

  47. Canha

    Cara, não conhecia seu site. Mas que bom que encontrei. aisheuaise.
    Taí um modo diferente de se aprender. Se mais livros fossem escritos assim, teríamos programadores melhores.
    Sucesso pra ti!
    Abraços

  48. Richard

    Maneiro. To aprendendo Python e acho que entendi o código.
    x%2 exibe o resto da divisão né… E depois == 0 pergunta se o resto foi zero?

    Acho que é isso mesmo.

  49. Luiz Fernando Ribeiro

    Concordo com o Japa.
    No meu caso eu prefiro usar o ‘for’, por ser muito mais legível para um programador que não conhece os detalhes da linguagem (no caso, Python).
    Já que o ‘for’ é “universal”, seria minha opcão!
    Saber escrever código compacto ou obscuro é bacana! Mas na hora de trabalhar quanto mais legível melhor :)

  50. marcus

    No Matlab, é só usar o comando

    [0:2:20]

    Mais simples ainda.

  51. Ricardo

    Na verdade dá pra escrever qualquer coisa em uma linha de Python, porque a linguagem continua Turing-complete mesmo com essa restrição. Coloquei uma demonstração disso no meu blog, pra quem quiser ver:

    http://www.ricbit.com/2008/05/python-one-liners-so-turing-complete.html

  52. O q usar??? - Pgina 2 - Under-Linux.org Fruns

    [...] Infelizmente conheo muito pouco de Pearl pra falar. Um blog Nerd que fez uma tirinha sobre phyton Nerdson não vai * escola Pythonic way of life __________________ " If you choose not to decide, you still have made a choice." [...]

  53. namekuseijin

    Paulino, certamente vc não está falando sério que o código ali é imcompreensível e coisa só de nerdson ou ainda que deveríamos reescrevê-lo em Java padrão, com javadoc e com diagramas de caso de uso?!

    Pensando bem, não responda. Você sabe que mundo tá muito ferrado das idéias mesmo quando piadas por email vêm com a explicação entre parênteses ou palitos de dentes vêm com instruções de uso… não há mais salvação para a humanidade.

  54. namekuseijin

    Boas tentativas, damnerd e ricardo, infelizmente não há realmente one-liner em C++, C#, Java ou outras mainstream, já que vc precisa criar um wrapper formal de programa para o compilador ficar feliz. Coisas como int main() {}; public static void Main() {} etc. Além dos imports usuais. É claro, sua IDE pode cuidar disso, mas não faz disso um one-liner.

    Pior, vc não pode simplesmente usar o one-liner na linha-de-comando, que é o principal uso de one-liners, afinal…

  55. cristiar1000

    Vai de cobol…

    perform varying i from 2 by 2 until i > 20 display i.

    Não tem if, mas tbm não é mágica!

  56. Anderson

    Mais fácil ainda…
    Bota seu irmão mais novo pra digitar pra vc! huhsuahsuahusuh
    Digita ai mulek!
    0 2 4 6 8 10 12 14 16 18 20 pronto!

    Bem mais fácil! hehe
    Pra quem não saca de programação é uma boa! rsrs

Mate aula você também!

Comentários ofensivos ou de conteúdo impróprio serão enviados para /dev/null.