Aula 14 - Python

Python online

Python Tutorial

Standard library

Historia

criando em 1989 por Guido van Rossum

python 3.0 (2008) não é backward compatible com o 2.0

2.7 é a ultima versão da familia 2.0

Guido deixou de ser o ditador benevolente vitalicio do python em 2018 por causa deste PEP 572 - atribuição em expressões (:=)

if (match := pattern.search(data)) is not None:
    # Do something with match

while chunk := file.read(8192):
   process(chunk)

[y := f(x), y**2, y**3]

filtered_data = [y for x in data if (y := f(x)) == 0]

PEP

Python Enhancement Proposals

implementações

paralelismo/concurrency

concurrency - nao necessariamente em paralelo, mas operaçoes que demoram muito (I/O) sao executadas “ao mesmo” tempo que outras operaçoes

paralelismo - operacoes sao realmente executadas em paralelo em diferentes cores/CPU ou mesmo computadores

O ambiente de execução do CPython nao permite concorrencia (interno - automático) por causa do GIL- global interpreter lock

para obter paralelismo de threads (dentro do mesmo processo) é preciso que o codigo tenha sido escrito em C. Isso é o caso para o numpy, pandas, etc. Uma funçao do numpy pode rodar varios threads em paralelo.

Tipagem Dinamica

Variáveis não precisam ser declaradas e não tem tipos

x = 90
x = "qwerty"
x = [3,4,56]

Basicamente, toda variável é um apontador para um valor.

id(x) retorna o valor do apontador armazenado na variável x

Tipos

básicos

no python >= 3.0, inteiros são unbounded (bignums) - pode não corresponder aos inteiros de hardware

float é o double do hardware - 53 bits de precisão e 11 de expoente

compostos

mutáveis e imutáveis

Trocar o valor de uma variavel que contem um tipo básico significa criar um novo valor e apontar a variável para esse novo valor.

x=5
id(x)
x=x+1
id(x)
x = [10, 20, 30, 40]
id(x)
x[1]
x[1] = 99
x
id(x)
x = [10, 99, 30, 40]
id(x)
x = (10, 20, 30, 40)
x[1]
x[1]= 99

atribuição

x=[1,2,3]
id(x)
y=x
id(y)
z=x[:]
id(z)

O jeito simples de pensar é que uma expressão do lado direito da atribuição retorna um apontador para um valor e nao o valor. Pode ser que o lado direito precisa ser avaliado e um valor é computado, mas o que é passado para o lado esquerdo é o apontador para esse valor.

atribuição apenas faz a variável do lado esquerdo apontar para esse apontador

a=2
b=a
id(a)
id(b)
b=b+1
a
id(b)
f=1+1
id(f)

Note que id(a) == id(f)

Python predefine inteiros pequenos (de -5 a 256)
https://realpython.com/lessons/small-integer-caching/

Listas ( e sequencias)

x = [10, 20 , 30, 40, 50]
x[0]
x[7]
x[-2]
x[-7]

slices

subsequencias de listas

x = [10,11,12,13,14,15,16,17,18]
x[2:5]

elementos nas posicoes 2 até antes do 5

Abreviações:

x[:3] => x[0:3]
x[3:] => x[3:final]

Pode ter passo diferente de 1

x[1:20:3]
x[::-1] - lista revertida

Pode atribuir valor a slices, de diferentes tamanhos

x[2:5] = [1,2]
x
x[2:5] = []
x

Copia rasa e copia profunda

[:] copia a lista (copia rasa)

a= [1,[2,3],4]
b=a[:]
b[0]=9
b
a
b[1][0]=99
b
a

https://docs.python.org/3/library/copy.html veja deepcopy

operadores, funções e metodos em lista

x = [1,
    2,
    3,
    ]

List comprehensions

como no Haskel mas com uma sintaxe diferente

[f(x) for x in fonte if condicao]

[x**2 for x in [2,3,4,5,6,7] if x % 2 == 0]

implementação de listas

Tuplas

sequencias como lista mas imutáveis

metodos de lista não funcionam

funções de lista funcionam.

x = (1,2,3,4,5)
x[1]
x[3:]
max(x)

pattern matching

Para atribuição (lado esquerdo são variáveis).

(a,b)  = (10,"qwerty")
(a,b) = 10, "querty"
a,b = (10,"querty")
a,b = 10 , "querty"
a,b = b,a
[a,b,c] = [1,4.5, "zzz"]
[a,*b] = [1,4.5, "zzz"]

python 3.10 introduz um outro pattern matching tipo switch (match - case https://www.python.org/dev/peps/pep-0636/#matching-sequences

testa por igualdade e por estrutura

match command.split():
    case []:
        ....
    case ["quit"]:
        print("Goodbye!")
        quit_game()
    case ["look"]:
        current_room.describe()
    case ["get", obj]:
        character.get(obj, current_room)
    case ["go", direction]:
        current_room = current_room.neighbor(direction)
    # The rest of your commands go here

Strings

x = "qwerty"
x[2]
x[2][2]
x = 'qwerty'
'wer' in x

Dicionários

x = { 'asd': 56, 'qwerty': -8, 'zxcv': 3}
x['qwerty']
x['zzz']
x['qwerty'] = 9
'zzz' in x

qualquer tipo imutável pode ser a chave, qq tipo pode ser o valor

metodos para dicionarios

Implementado como uma hash table que usa a funcão interna hash para gerar um indicator para cada valor. https://stackoverflow.com/questions/327311/how-are-pythons-built-in-dictionaries-implemented

Set

sets

None

tipo com apenas um valor None.

for

list(range(10))
list(range(2,10))
list(range(2,10,3))

for i in range(len(lista)):

list converte o objeto para listas

Exercícios