Python para iniciantes – Tuplas (Objetos Imutáveis)

Tuplas são estruturas de dados muito parecidas com as listas, mas com algumas diferenças, uma delas e mais importante, é que as tuplas são imutáveis, ou seja, após criadas não podem ter seu estado alterado e qualquer operação feita sobre elas irão gerar um novo objeto, ou seja, uma nova tupla.

Para definir uma tupla utilizamos dois parênteses ( ), ou não, rs, como assim, vamos lá:

Como visto no exemplo acima existem muitas formas de se definir uma tupla, mas uma delas me chama atenção, que é o segundo exemplo, onde definimos a tupla sem parênteses, assim t = ‘a’, ‘b’, porque diferente do que se pensa, não são os parênteses que definem uma tupla, mas as vírgulas, bem interessante isto, portanto o exemplo abaixo também criaria uma tupla.

Enquanto este outro exemplo não:

Como encontrar um elemento em uma tupla:

Fazendo Slicing em uma tupla:

Tuplas tem poucos métodos, apenas dois para ser mais exato:

Operações com tuplas:

Por que utilizar tuplas?

Tuplas são mais rápidas que listas. Se você precisa apenas definir um conjunto de valores constantes e depois percorrê-los de alguma forma, então opte por tuplas.

Deixo aqui também um pensamento sobre tuplas e listas:
“Tupla congela uma Lista e Lista descongela uma Tupla.”

Obrigado e até próxima :)

 

Python para iniciantes – Listas (Objetos mutáveis)

Listas em Python são estrutura de dados que podem armazenar qualquer tipo de valor, inteiros, strings, floats, funções, classes, … e outros tipos.

- Podemos dizer que as Listas são como os arrays de outras linguagens de programação.
- As listas não armazenam realmente os objetos dentro dela, mas sim a referência de memória desses objetos.

Criando uma lista:

Como mostrado acima é bem simples criar uma Lista de dados em Python, basta envolver os elementos com colchetes [ ] e separar os elementos por vírgulas.

Fazendo Slicing em uma Lista:

Adicionando elementos em uma Lista:

Removendo elementos de uma lista:

Operações em Listas:

Porque Lista são objetos mutáveis (muito importante):

Um Objeto mutável é aquele que pode ser alterado após a sua criação, ou seja, podemos alterar o estado do objeto sem termos que criar uma cópia do mesmo. Por exemplo:

Repare que as operações na lista acima afetaram sempre o mesmo objeto, sem criar outros.

Referências em Listas:

O exemplo acima, mostra que em Python atribuições a partir de Listas geram referências, por isso a variável “L” e “w” apontam para o mesmo endereço de memória.

Se tudo é referência então como criar uma cópia de uma Lista?

Observe que endereço de memória não é mais o mesmo, ou seja, temos duas variáveis, cada uma apontando para seu endereço de memória.

Até o próximo post :)

Python para iniciantes – Strings (Objetos Imutáveis)

“Python para Iniciantes”, nesta série de posts vamos abordar um pouco sobre essa linguagem incrível que é o Python e que mudou para melhor meu dia dia como desenvolvedor WEB e também a de milhares de pessoas que querem e precisam entregar projetos de qualidade em prazos relativamente curtos. A intenção dessa aula, é apresentar ao estudante uma visão de como trabalhar como Strings em Python, então vamos lá: Tudo em Python é objeto, inclusive as strings:

No exemplo acima o tipo da variável my_first_string é str, que é o tipo que representa strings em Python. Em Python Strings são imutáveis. O que é isso? Objetos imutáveis são aqueles que não podem ser alterados, ou seja, esses mantém seu estado após criados e quando existe a necessidade de serem alterados eles se multiplicam, vamos a um expemplo:

No exemplo acima não foi possível atribuir o valor “A” na sexta posição da string “menino“, pois como o erro lançado nos diz: “O tipo string não suporta atribuição de item”, portanto não é possível alterar apenas uma posição da variável “va“. Para tal precisariamos atribuir novamente o valor da variável va:

Resumindo: qualquer operação em uma string, sempre gera um novo objeto e isso também vale para os tipos int, float, long, complex, tuple … Tendo em mente que uma nova string será gerada a cada operação, devemos tomar cuidado com coisas assim:

Pois dessa forma o Python vai concatenar as strings assim (((“muitas” + “strings”) + “para”) + “concatenar”), de duas em duas, gerando mais processamento. Portanto o jeito pythonico de se fazer é utilizando o método join(), que concatena tudo de uma única vez, assim:

Como retornar o tamanho de uma string?

É bem tranquilo, basta utilizar a função built-in len().

Como retornar uma parte da string (substring) em Python?

A sintaxe para retornar o pedaço de uma string é nome[START:END:STEP]
Mas antes de começar vamos entender a diferença entre Python índices(index) e slices.
Índices(index) enumeram os elementos enquando slices enumeram os espaços entre os elementos. A imagem abaixo pode explicar melhor:

slicing python

Na sintaxe nome[START:END]
START reflete as duas primeiras linhas da imagem acima
, que equivale a posição real, iniciando em zero da esquerda para direita e em -1 da direita para a esquerda. Portanto falamos que o índice START é fechado.
END reflete as duas últimas linhas da imagem acima
, que equivale a (posição desejada - 1) e por isso falamos que o índice END é aberto.

Por índice:
nome[index] # caracter que está na posição index, que equivale à nome.__getitem__(index)

Por slicing:
nome[start:end]
# caracteres que comecem da posição start até end-1
nome[start:] # caracteres que comecem da posição start e vão até o fim
nome[:end] # caracteres que comecem da posição 0(do início) até end-1
nome[:] # caracteres que comecem da posição 0 até o fim. Faz uma cópia da string

Indices negativos também são permitos

Por índice:
nome[-1]
# caracteres começam de trás para frente, onde -1 é o último item da string.

Por slicing:
nome[-2:] # caracteres que comecem do penúltimo até o fim da string
nome[:-2] # pega todos os caracteres menos os dois últimos.

Temos também os passos (steps)

a[start:end:step] # caracteres que comecem da posição start até end-1, onde step é um valor numérico e inteiro que indica o passo, por exemplo:
nome[:5:2] # caracteres que comecem da posição 0 até 5-1, pulando de 2 em 2

Alguns métodos interessantes do objeto String:

Obrigado e até a próximo post :)

Diferenças entre o Python 2 e o Python 3

Em breve, mais cedo ou mais tarde, teremos que migrar uma aplicação feita em Python 2.x para Python 3, não tem jeito é o nosso destino e porque migrar?

Como está escrito na wiki oficial do Python:
Python 2.7 é legado e o Python 3 é o presente e o futuro da linguagem.

Python 3 foi lançado em 2008, já a versão final do Python 2, a versão 2.7, saiu por volta de 2010, mas já com a decisão que a família 2.x não teria grandes releases. E desde então a versão 3.x vem sendo melhorada e conta com versões estáveis desde então, como por exemplo as versões 3.3 em 2012, 3.4 em 2014 e 3.5 em 2015.

Uma das primeiras mudanças que vemos no Python 3 é na função print, que agora realmente é uma função:

Python 2:

Python 3:

Podemos também usar alguns argumentos novos na função print como por exemplo o end e o sep:

Divisão entre números inteiros mudou um pouco:

No Python 2.x a divisão entre 3 / 2 sempre retorna 1, mas no Python 3 o resultado é 1,5 (que bom né, rs), porque agora a divisão não depende mais do tipo do denominador e do numerador.

Se for necessário utilizar o comportamento antigo utilize duas barras, assim: 3 // 2

True e False agora são palavras reservadas:

No Python 2 podiamos fazer algumas coisas estranhas como:

No Python 3 finalmente isso não é mais possível:

Raising exceptions:

No Python 2.x podiamos usar a velha e nova sintaxe. No Python 3 podemos usar apenas a nova:
Python 2:

Python 3:
Só assim:

Manipulando exceções:

No Python 3 temos que usar obrigatoriamente a palavra chave “as
Python 2:

Python 3:

Unpacking avançado:

Agora podemos fazer coisas do tipo:

“keyword-only” arguments:

Com a função acima em mente vamos imaginar que você precisa que o parâmetro option seja usado da forma como está no contrato da função, ou seja, deve ser passado como no exemplo abaixo:

>>> fn(1, 2, option=False)
e nunca
>>> fn(1, 2, 3) # -> desse modo, o parâmetro option teria o valor 3 e não é o que queremos.

Felizmente no Python 3 isso é possivel, basta adicionar o argumento de quantidade indefinida de parâmetros posicionais, aqui representado por *args, como no exemplo abaixo:

E assim dessa forma podemos chamar a função fn desse jeito:
>>> fn(1, 2, 3): # -> o parâmetro de valor 3 foi enviado para o argumento *args.
E o parâmetro option continua com o valor True.

Poderiamos utilizar dessa forma, que também funcionaria:
>>> fn(1, 2, 3, 4, option=False) # -> os parâmetro 3 e 4 foram enviados para o argumento *args.

Tudo agora é iterator

Se você fizer no Python 2.x:

Tem grandes chances do seu computador travar, bem travado. Por que? Porque a função range() tenta alocar neste caso um espaço na memória com 100000000 posições, detonando a memória da máquina. Já no Python 3 isso não acontece porque a função range() retorna uma espécie de iterator que vai liberando a memória a cada loop.
Com isso a função xrange() do Python 2.x foi eleminada sem dó, pois o range() agora faz o papel que ela fazia.
Por isso em Python 3, range, zip, map, list, etc, são todos iterators.
Se você precisa de uma lista basta fazer isto: list(range(10))

Comparar tudo com tudo, não pode mais:

Python 2:

something_is_worng.jpg

No Python 3 isso não pode mais, melhor assim né:

O método .next() dos iterators foi para o /dev/null

No Python 2.x podemos utilizar a função built-in next() e também o método .next() de um iterator. Já no Python 3 isso mudou, ficamos apenas com a função next().
Python 2:

Python 3:

O método has_key(), aquele dos dicionários, não existe mais:

Em Python 2, poderia ser feito:

No Python 3, temos que usar o operado in:

Variáveis de controle em List comprehensions não mais afetam o escopo a sua volta:

Python 2:

Python 3:

Finalmente o tipo enumerado faz parte da biblioteca padrão do Python:

No Python 3.4, agora temos:

O raw_input não existe mais:

No Python 2.x temos o raw_input e o input para fazer a leitura dos dados do teclado. O raw_input lê strings em geral e o input lê apenas números.
No python 3 existe apenas o input que lê tudo como strings, então se você precisa de uma entrada numérica basta converter assim:

Nome de variáveis unicode:

Valeuuuu, :)

Referências que usei para criar este post:
https://docs.python.org/3/whatsnew/3.0.html
https://asmeurer.github.io/python3-presentation/slides.html#1
https://pythonhelp.wordpress.com/2013/09/01/o-que-mudou-no-python-3/
http://sebastianraschka.com/Articles/2014_python_2_3_key_diff.html#future_module

Utilizando Pyenv e Pyenv-virtualenv e aposentando o virtualenv “ou não”.

pyenv-virtualenvUtilizei por muito tempo o virtualenv para criar ambientes python isolados e assim com tranquilidade, instalar pacotes python a vontade sem ter que me preocupar com versões e compatibilidades entre os pacotes, porque estes estariam sempre isolados no seu ambiente virtual. Isso é legal, muito legal, mas agora além de me preocupar com os pacotes instalados, também tive a necessidade de escolher a versão do python que eu queria usar no meu ambiente virtual. E isso o virtualenv não resolve por completo. Por exemplo:

Quero criar um ambiente virtual com a versão do Python 2.7.6 e um outro com a versão 3.5.1. E ai, como faço? É ai que entra o pyenv + pyenv-virtualenv, pois com o pyenv conseguimos instalar facilmente versões diferentes do python na mesma máquina e alternar entre elas apenas com um simples comando. Já o pyenv-virtualenv é um plugin do pyenv que nos permite criar ambientes isolados escolhendo a versão do Python antes de criá-los.Chique né e como começar?

Primeiro vamos instalar algumas dependências:

Agora vamos instalar o pyenv, com o comando abaixo (Ps: este é o comando que encontrei no site oficial, ver aqui):

Após finalizado a instalação, adicione as linhas abaixo ao seu .bashrc:

E para surtir efeito as linhas adicionadas acima, rode:

Com isso o pyenv está instalado e se digitarmos pyenv na console veremos:

Agora podemos listar as versões do python instaladas, digitando:

Para listar as versões python disponíveis:

E assim podemos escolher qual versão do python instalar, vou escolher a 3.5.1

agora digite novamente:

e você verá que existem duas versões instaladas. E para escolher a versão 3.5.1, basta digitar:

agora digite python na console e você verá que a versão global do python no sistema é a 3.5.1:

Até aqui tudo ok e legal, mas precisamos criar ainda nosso virtual environment, para isso vamos instalar o plugin pyenv-virtualenv:

Caso você receba a mensagem:

É porque pyenv-virtualenv foi instalado logo lá no começo junto com a instalação do pyenv.

Enfim vamos criar nosso primeiro virtualenv:

ative-o digitando:

agora digite python e você verá que a versão usada para criar o virtualenv foi a padrão que veio instalada no sistema antes mesmo de você instalar o pyenv. No meu caso foi a 2.7.6

Para criar com outra versão do python, basta digitar por exemplo:

Agora podemos criar ambientes virtuais isolados como o virtualenv fazia mas com uma vantagem, ainda podemos escolher qual versão do python usar, legal né.

Quanto ao título deste post [ Utilizando Pyenv e Pyenv-virtualenv e aposentando o virtualenv "ou não". ], ficou escrito desta forma porque estudando o pyenv e o “original” virtualenv (aquele de raiz), descobri que também é posível escolher a versão do python ao se criar um ambiente virtual com o nosso velho amigo “virtualenv”, desta forma:

Aqui criamos um ambiente virtual a moda antiga, mas com a versão atual do python que foi setada pelo comando pyenv global. Bem interessante também.

Ficamos por aqui, abraços e até o próximo post.