Aprenda os fundamentos do Python em 30 Dias  —  Dia 6 (Tuplas e Conjuntos)

Aprenda os fundamentos do Python em 30 Dias  —  Dia 6 (Tuplas e Conjuntos)

Original: medium.com – devops-challenge


Tuplas

Tuplas em python são seqüências imutáveis ​​de objetos arbitrários, uma vez criados eles não podem ser alterados (substituídos/removidos) e novos elementos não podem ser adicionados.

Similar à lista mas delimitado por parênteses ao invés de colchetes

>>> a = (1,2,3)
>>> a
(1, 2, 3)
>>> type(a)
<class 'tuple'>

Podemos acessar o elemento usando a indexação

>>> a[0]
1

Podemos usar len() para encontrar o número de elementos

>>> len(a)
3

Podemos iterá-lo usando loop

>>> for i in a:
...   print(i)
...
1
2
3

Concatenar usando o operador +

>>> a
(1, 2, 3)
>>> b = (4,5,6)
a + b
(1, 2, 3, 4, 5, 6)

Repetição pode ser feito usando o operador *

>>> a * 2
(1, 2, 3, 1, 2, 3)

Como mencionado acima tuplas são imutáveis, por isso se tentarmos alterá-lo, ele resultará um TypeError

>>> a[0]= 4
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment

Uma coisa a notar é que não podemos usar um objeto ** com um único elemento** dentro do parêntesis como uma tupla porque o Python o tratará como um inteiro

>>> b = (10)
>>> type(b)
<class 'int'>

Para uma tupla de um único elemento, devemos incluir uma vírgula à direita do elemento

>>> b = (10,)
>>> type(b)
<class 'tuple'>

Mas então como podemos especificar as tuplas vazias? Muito simples, para fazer isso basta usar parênteses vazios.

>>> c = ()
>>> type(c)
<class 'tuple'>

As tuplas são úteis para retornar vários valores

>>> def minmax(ellist):
...   return min(ellist), max(ellist)
...
>>> a = [1,2,3,4,5,6]
>>> minmax(a)
(1, 6)

NOTA: Mais informações sobre iteração e funções veremos em um capítulo futuro.

O desempacotamento de tuplas (tuple unpacking) nos permitem desestruturaá-la diretamente em referências nomeadas

>>> min, max = minmax(a)
>>> min
1
>>> max
6

Podemos facilmente trocar (swap) variáveis ​​usando tuplas

>>> a = 5
>>> b = 10
>>> a,b = b,a
>>> a
10
>>> b
5

Veja como o mesmo código sem tupla fica mais verboso

>>> x = 4
>>> y = 5
>>>
>>> temp = x
>>> x = y
>>> y = temp
>>> x
5
>>> y
4

Alguns métodos das tuplas

index()

Quando precisamos descobrir o índice de um valor específico

>>> a = (1,2,3,1)
>>> a.index(1)
0

count()

Conta quantas vezes um dado valor aparece em tupla

>>> a = (1,2,3,1)
>>> a.count(1)
2

Agora pergunta é onde eu vou usar tupla?

Suponha que vamos escrever um programa onde passaremos um objeto e precisamos ter certeza de que ele não será alterado, nesses casos tupla pode ser a nossa solução por sua principal característica (imutable)

Exercício

1: Escreva uma tupla que só pode imprimir valores pares

MyTup = ("Bem-vindo", "ao", "mundo", "da","super", "tupla")

#Saída
("Para", "mundo", "tupla")

Conjuntos

Conjuntos (sets) são uma coleção desordenada de elementos exclusivos. A coleção é mutável, ou seja, os elementos podem ser adicionados/removidos do conjunto, mas cada elemento deve ser ele próprio imutável muito semelhante às chaves keys de um dicionário.

Conjuntos são semelhantes aos dicionários (assim como eles, usam chaves), mas cada item é um único objeto ao invés de um par unido por dois pontos.

>>> c = {1,2,3,4}
>>> c
{1, 2, 3, 4}
>>> type(c)
<class 'set'>

Os conjuntos são usados ​​principalmente para descartar itens duplicados

>>> d = {1,2,3,3,2}
>>> d
{1, 2, 3}

Os conjuntos são iteráveis

>>> for i in d:
...   print(i)
...
1
2
3

Para adicionar elementos ao conjunto usamos o método add()

>>> e
{1, 2, 3}
>>> e.add(4)
>>> e
{1, 2, 3, 4}

Se tentarmos adicionar um elemento que já existe não haverá efeito e nem será lançado qualquer erro.

>>> e.add (4)
>>> e
{1, 2, 3, 4}

Para adicionar vários elementos

>>> e.update([7,8,9])
>>> e
{1, 2, 3, 4, 7, 8, 9}

Para remover um elemento do conjunto

>>> e.remove(7)
>>> e
{1, 2, 3, 4, 8, 9}

NOTA: Tentar remover um elemento que não existe lançará um erro

>>> e.remove (7)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 7

# outro método análogo é o  método é descartar
>>> e.discard(1)
>>> e
{2, 3, 4}
# não produz qualquer erro mesmo o membro não estando presente
>>> e.discard (1)

O outro uso útil de tipos de conjunto é o grupo poderoso de operações. Estes permitem-nos facilmente calcular conjuntos união, conjunto diferença, conjunto interseção e subconjuntos.

# Diferença
>>> a = {1,2,3}
>>> b = {3,4,5}
>>> a.difference(b)
{1, 2}
# Intersecção
>>> a.intersection(b)
{3}
# subconjunto Subset
>>> a.issubset(b)
False
>>> b.issubset(a)
False

Final da lição do Dia 06, Em caso de dúvidas ou qualquer outra discussão, este é o link para o canal (Comunicação somente em Inglês – english only) Python Slack channel http://devops-myworld.slack.com


Aprenda os fundamentos do Python em 30 Dias  —  Dia 5 (Dicionários)

Aprenda os fundamentos do Python em 30 Dias — Dia 5 (Dicionários)

Original: medium.com – devops-challenge


Os dicionários são mapeamento não ordenado de chaves únicas imutáveis ​​para valores mutáveis. Dicionários são delimitados com chaves e contêm pares key-value separados por vírgula com cada par encadeado por dois pontos.

>>> teste = {"fname": "pra", "lname": "lak", "idade": 30}
>>> teste
{'Fname': 'pra', 'lname': 'lak', 'idade': 30}

Os valores são acessíveis por chaves

>>> teste["fname"]
pra

Nunca devemos confiar na ordem dos itens no dicionário (ela é aleatória) e pode até variar entre diferentes execuções do mesmo programa.

De maneira similar às listas, a cópia do dicionário é superficial por padrão, copiando apenas as referências aos objetos de chave e de valor, e não os próprios objetos de valor

Duas maneiras de copiar o dicionário

1: Usar o método copy()

>>> teste1 = teste.copy()
>>> teste1
{'Fname': 'test', 'lname': 'lak', 'age': 30}

2: Simplesmente passando para o construtor dict

>>> teste2 = dict(teste)
>>> teste2
{'Fname': 'test', 'lname': 'lak', 'age': 30}

## Atualizando Dicionário
```python
>>> teste["valor"] = 5
>>> teste
{'fname': 'teste', 'lname': 'lak', 'idade': 30, 'valor': 5}

Dicionários são iteráveis ​​e podemos usá-lo com loops

>>> for i in teste:
...   print("Valor da key " + i + " => " + str(teste[i]))
... 
Valor da key fname => pra
Valor da key lname => lak
Valor da key idade => 30
Valor da key valor => 5

Se estamos à procura de chaves, então temos método keys()

>>> teste.keys()
dict_keys(['fname', 'lname', 'idade', 'valor'])

Da mesma forma, podemos procurar apenas valores mediante o uso do método values()

>>> teste.values()
dict_values(['pra', 'lak', 30, 5])

Para se obter ambas as chaves e valores (key-values) temos o método items()

>>> teste.items()
dict_items([('fname', 'pra'), ('lname', 'lak'), ('idade', 30), ('valor', 5)])

Só para resumir

1. chaves

  • Deve ser único
  • Tipo imutável (int, float, string, tuple, bool)
  • Cuidado com o tipo float como uma chave (se float tem problema de precisão, podemos não ser capazes de descobrir o que estamos procurando)

2. valores

  • Qualquer tipo (imutável ou mutável)
  • Pode ser duplicado
  • Valores de dicionário podem ser listas, até mesmo outros dicionários

3. Nenhuma ordem para chaves e valores

A biblioteca padrão do Python fornece o módulo pprint (cópia bonita [pretty print] ) que sabe como imprimir de maneira elegante todas as estruturas de dados, incluindo dict.

>>> from pprint import pprint
>>> pprint(teste)
{'fname': 'pra', 'idade': 30, 'lname': 'lak', 'valor': 5}

Compreensão do Dicionário

A compreensão de dicionários permite expressar a criação de dicionários em tempo de execução

Sintaxe

{key: value for(key, value) in iterável}

A compreensão de dicionários é bastante útil se quisermos inverter o dicionário (não é tão comum como a compreensão de lista além de tornar o código mais difícil de ler)

>>> import pprint
>>> D1 = {'a': 1, 'b': 2, 'c': 3}
>>> D2 = {v: k for k,v in D1.items()}
>>> pprint(D2)
{1: 'a', 2: 'b', 3: 'c'}

Final da lição do Dia 05, Em caso de dúvidas ou qualquer outra discussão, este é o link para o canal (Comunicação somente em Inglês – english only) Python Slack channel http://devops-myworld.slack.com


Copyright – Learn Python Fundamental in 30 Days  — [medium.com – devops-challenge] http://medium.com/devops-challenge

Aprenda os fundamentos do Python em 30 Dias  —  Dia 4 (Listas)

Aprenda os fundamentos do Python em 30 Dias — Dia 4 (Listas)

Original: medium.com – devops-challenge


Básico

  • Lista é uma seqüência ordenada que contém vários valores (seqüência mutável)
  • Denotado por colchetes []
  • Contêm elementos(homogéneos(todos inteiros)/mistos(não comuns))
    python
    &gt;&gt;&gt; x = [1,2, 'abc', 2.5]
    &gt;&gt;&gt; x
    [1, 2, 'abc', 2.5]

    Representação dos índices e elementos de uma lista

enter image description here

Podemos acessar o item na lista com um índice inteiro que começa com 0 (não 1)

>>> x [0]
1

Podemos usar índice negativo para referir o último item na lista

>>> x[-1]
2.5

Para obter vários itens da lista use slice

>>> x[0:2]
[1, 2]
#Basicamente pegue todos os valores da lista
>>> x[0:]
[1, 2, 'abc', 2.5]
# Tentar pegar algo fora do intervalo resulta em um erro
>>> x[4]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range

Lista são mutáveis (mutable), atribuindo um valor a um elemento em um índice muda o valor daquele elemento

>>> a = [1,2,3]
>>> a[0] = 4
>>> a
[4, 2, 3]

Podemos combinar duas listas através do operador concatenação +

>>> L1 = [1,2,3]
>>> L2 = [4,5,6]
>>> L1 + L2
[1, 2, 3, 4, 5, 6]

Toda a função que trabalha com strings funciona da mesma forma com a lista, por exemplo: len()

>>> len(x)
4

Para excluir o valor da lista use del

>>> del x[0]
>>> x
[2, 'abc', 2,5]

Para descobrir um valor em uma lista use o operador in

>>> 'l' in em 'olá'
True

Para descobrir um valor não existe em uma lista use o operador not in

>>> 'l' not in 'olá'
False

Uso do laço para for loop com lista, serve para iterar sobre os valores em uma lista

>>> for i in x:
...     print(i)
... 
2
abc
2.5
>>> 

A função range() retorna valores como lista que podemos passar para a função list() se precisarmos um valor atual

>>> list(range(0,4))
[0, 1, 2, 3]

Vamos dar mais um exemplo

>>> itens = ["a", "b", "c", "d"]
>>> for i in range(len(itens)):
...     print("Valor em" + str(i) + "é:" + itens [i])
...
Valor em 0 é: a
Valor em 1 é: b
Valor em 2 é: c
Valor em 3 é: d

Trocando Variáveis

>>> a, b, c = 1,2,3
>>>> a
1
>>> b
2
>>> c
3

Converter lista em cadeias ou vice-versa

Podemos converter uma string em uma lista passando-a para a função list()

>>> list('Olá')
['O', 'l', 'á']

Podemos usar o método split() das string para dividir em um caractere

>>> s = 'hello'
>>> s.split ('e')
['h', 'llo']

# !!! Cuidado
>>> s.split ('l')
['he', '', 'o']

Podemos usar o método join() para transformar uma lista de caracteres em uma string

>>> s = ["a", "b", "c"]
>>> "_".join(s)
'a-b-c'

Métodos de Listas

Métodos são funções que são chamados para cada valor valore. As listas têm vários métodos:

index()

Método da lista que retorna o índice de um item na lista

>>> teste = ["a", "b", "c", "d"]
>>> test.index ("a")
0

# o metodo index levantará uma exceção se ele 
# não encontrar o valor
>>> test.index("e")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'e' is not defined

# Agora, no caso de lista duplicada, apenas 
# retorna o índice do primeiro valor
>>> teste = ["a", "b", "c", "d", "a", "b"]
>>> test.index ("b")
1

append()

Esse método adiciona um valor ao final de uma lista

>>> teste.append("z")
>>> teste
['a', 'b', 'c', 'd', 'a', 'b', 'z']

insert()

Métodos que adiciona um valor em qualquer lugar dentro de uma lista

>>> teste.insert(0, "hola")
>>> teste
['Hola', 'a', 'b', 'c', 'd', 'a', 'b', 'z']

pop()

Método que remove o elemento no final da lista, retorna o elemento removido

>>> L1.pop()
3
>>> L1
[1, 2]

# Podemos até armazenar o valor do elemento removido
>>> x = L1.pop()
>>> x
3

remove()

O método remove um item de uma lista especificado pelo seu valor

>>> teste.remove("a")
# Somente a primeira incidência desse valor é removida
>>> teste
['Hola', 'b', 'c', 'd', 'a', 'b', 'z']

reverse()

Uma lista pode ser revertida chamando esse método

>>> a = [2,5,1,3,6,4]
>>> a.reverse()
>>> a
[4, 6, 3, 1, 5, 2]

sort()

Esse método classifica os itens em uma lista (Atenção: ele muda a lista original)

>>> test1 = [8,3,9,4,6,3]
>>> test1.sort()
>>> teste1
[3, 3, 4, 6, 8, 9]

Caso quisermos classificar uma combinação de números e strings, o python lança um erro porque ele não sabe como classificá-lo

>>> teste2 = [1,3,2,6,5, "a", "b"]
>>> teste.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'str' and 'int'

A ordenação usando ASCII-betical funciona ordenando as maiúsculas primeiro

>>> teste3 = ['a', 'b', 'A', 'B']
>>> teste3.sort ()
>>> teste3
['A', 'B', 'a', 'b']

Talvez isso não seja exatamente o que queremos quando ordenamos alfabeticamente. Gostaríamos de ‘A’ deve seguido por ‘a’. Para fazer isso passar como argumento str.lower para o método sort() que tecnicamente converter tudo para minúsculas

>>> teste3.sort(key=str.lower)
>>> teste3
['A', 'a', 'B', 'b']

# É importante o uso da chave 'key', onde usamos 
# len como uma key(aqui a classificação acontece 
# com base no comprimento)
>>> b = ['Olá', 'como', 'está', 'você', 'Sr.', 'Hans']
>>> b.sort(key=len)
>>> b
['Olá', 'Sr.', 'como', 'está', 'você', 'Hans']

NOTA: Estes métodos funcionam na lista (in place), em vez de devolver um novo valor de lista, ou seja, eles alteram a lista original.

sorted()

È uma função interna (built-in) que classifica qualquer série iterável e retorna uma lista (não muda a lista original)

>>> x = [5,2,3,1]
>>> sorted(x)
[1, 2, 3, 5]
>>> x
[5, 2, 3, 1]

count()

Essa função retorna o número de elementos correspondentes na lista

>>> a = [1,2,3,4,1,23,5,6]
>>> a.count(1)
2

extend()

Usado para estender uma lista

>>> L1
[1, 2, 3]
>>> L2
[4, 5, 6]
>>> L2.extend(L1)
>>> L2
[4, 5, 6, 1, 2, 3]

# Aqui está a principal diferença entre acrescentar e estender, se usarmos anexar no lugar de estender (lista aninhada)
>>> L1.append(L2)
>>> L1
[1, 2, 3, [4, 5, 6]]

Precisamos ter muito cuidado com algumas coisas quando manipulamos as listas

>>> teste = [1,2,3,4]
>>> teste1 = teste
>>> teste1
[1, 2, 3, 4]
>>> test1[0] = 9
>>> teste1
[9, 2, 3, 4]
>>> teste
[9, 2, 3, 4]

Você percebeu que alteramos apenas o valor de teste1, mas o valor de teste também foi alterado?

A razão é que, quando criamos esta lista (teste), Python criou esta lista na memória do computador, mas é atribuída uma referência para teste. Quando executamos o seguinte comando

>>> teste1 = teste

uma referência é copiada para teste1 referenciando a mesma lista teste (veja a figura a seguir) e isso pode causar todo o tipo de erros estranhos, por isso, tenha muito cuidado ao lidar com listas.

associação de variáveis à mesma referência de memória
(Por favor algum colaborador pode fazer essa figura em português para mim?)

Não temos esse tipo de problemas com valores imutáveis ​​como strings/tuplas, pois seus valores não podem ser substituídos por novos valores.

>>> a = "abc"
>>> b = a
>>> b = "efg"

# A mudança em b não afetará a
>>> b
'efg'
>>> a
'abc'

Vamos mais fundo no mesmo conceito, como você vê é apenas uma referência que está mudando aqui. Agora não temos maneira de chegar a x = 100, de modo que em algum ponto do tempo o coletor de lixo Python cuidará dele.

id()

Retorna um identificador exclusivo para um objeto

>>> x = 100
>>> id(x)
4340331440
>>> x = 50
>>> id(x)
4340329840

Então, para lidar com estes tipos de questões em que queremos uma lista completamente separada, temos módulo chamado copy que também tê um módulo chamado deepcopy que criam uma nova lista e retornam a referência para esta nova lista.

>>> x = [1,2,3]
>>> import copy
>>> y = copy.deepcopy(x)
>>> y
[1, 2, 3]
>>> y[0] = 4
>>> y
[4, 2, 3]
>>> x
[1, 2, 3]

outra técnica é o fatiamento completo

>>> a = [4,5,6]
>>> b = a[:]
>>> b
[4, 5, 6]
>>> id(a)
4325208200
>>> id(b)
4325208328
>>> b[0] = 10.
>>> b
[10, 5, 6]
>>> a
[4, 5, 6]

Algumas outras coisas a serem observadas ao trabalhar com listas

>>> def remove_dups(L1,L2):
...   for i in L1:
...     if i in L2:
...       L1.remove(i)
... 
>>> L1 = [1,2,3]
>>> L2 = [1,2,4]

Saída

>>> remove_dups(L1,L2)
>>> L1 #<- Corrigir, debug código, deve ser apenas 4
[2, 3]
>>> L2
[1, 2, 4]

A razão para isso está em como o Python usa contador interno para manter o controle do índice que está no loop. À medida que a alteração muda o comprimento da lista Python não atualiza o contador e os loops nunca vêem o segundo elemento. Para evitar esse tipo de problemas vejamos uma implementação maneira melhor

>>> def remove_dups (L1, L2):
...   L1_copy = L1 [:]
...   for i in L1_copy:
...     if i in L2:
...       L1.remove(i)
...

Saída

>>> L1 = [1,2,3]
>>> L2 = [1,2,4]
>>> remove_dups(L1, L2)
>>> L1
[3]
>>> L2
[1, 2, 4]

Compreensão de Lista

Compreensões (list comprehension) são uma sintaxe Concisa para descrever listas em um estilo declarativo ou funcional.

A sintaxe se parece com isso

[expr(item) for item in iterable]

Agora vamos dar uma olhada num exemplo simples

>>> y = "Bem-vindo ao mundo do python".split()
>>> comprimento = []
>>> for i in y:
...   comprimento.append(len(i))
...
>>> comprimento
[9, 2, 5, 2, 6]

Agora vamos escrever o mesmo exemplo usando compreensão de lista

>>> [len(x) for x in y]
[9, 2, 5, 2, 6]

Final da lição do Dia 04, Em caso de dúvidas ou qualquer outra discussão, este é o link para o canal (Comunicação somente em Inglês – english only) Python Slack channel http://devops-myworld.slack.com