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]
CPython é a “padrão” (versão 3.10 lançada em Outubro 2021) - nao confundir com Cython que é uma linguagem para programação em baixo nivel em Python que compila para C.
micropython - para sistemas embarcados https://micropython.org/
IronPython - para o .NET https://ironpython.net/ (versão 3.4)
Jython - converte para bytecode do Java https://www.jython.org/ (versão 2.7)
pypy - JIT compiler https://www.pypy.org/index.html
pypy normalmente esta de 1 a 2 números abaixo a subversão do CPython
nao confunda pypy with PyPi (instalador mais tradicional de pacotes python)
stackless python https://github.com/stackless-dev/stackless/wiki
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
não há paralelização automática - se esse comando esta demorando muito então já começe o outro
o programador pode criar código que explicitamente roda em threads (start/synchronize/etc) mas provavelmente ele não roda realmente em threads https://realpython.com/intro-to-python-threading/
pacote asyncio https://www.youtube.com/watch?v=GpqAQxH1Afc a partir de 3.10
há um paralelismo em batch - outro Python sera inicializado e eles se comunicam usando pipes mas não ha memoria compartilhada multiprocessing e concurrent.futures
esses podem criar um “modelo de memoria compartilhada” para o programador mas nao é realmente compartilhada no baixo nivel
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.
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
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
[2, 3, "abc", [], 6.7]
"querty"
ou 'querty'
(1, "abc", 2)
{ "abc":4, "de":9, "aav": -3}
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
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/
indexação começando em 0
indices não podem passar do fim
indices negativos - do fim para o começo
x = [10, 20 , 30, 40, 50]
x[0]
x[7]
x[-2]
x[-7]
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 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
len(l) tamanho
l.append(v) insere v no final de l
x in l - True se x aparece na lista l
x not in l
l1 + l2 - append
5 * [1,2,3] = [1,2,3,1,2,3,1,2,3]
lista1 < lista2 - ordem lexicográfica
lista2 == lista2
max(l) - maior valor em l
l.sort - modifica l (mas nao retorna nada)
sorted(l) - retorna nova lista ordenada
del x[1] - remove - é um operador e não uma função (sem parênteses) ou metodos (sem ponto).
lista (e tuplas e dicionarios podem terminar com
,
x = [1,
2,
3,
]
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]
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)
Para atribuição (lado esquerdo são variáveis).
(a,b) = (10,"qwerty")
,
são
implicitamente tuplas(a,b) = 10, "querty"
a,b = (10,"querty")
a,b = 10 , "querty"
a,b = b,a
*var
é para o resto da lista[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
sequencia
ente ” ou ’
imutáveis
caracteres Unicode,
sintaticamente, não existe o tipo caracter
x = "qwerty"
x[2]
x[2][2]
in
testa por substringsx = 'qwerty'
'wer' in x
s.split() - words do haskell mas permite outros separadores
s.splitlines() - lines do haskell
outros metodos para strings e mais outros
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
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
tipo com apenas um valor None.
is None
para testaro comando for passeia pelos elementos de uma sequencia (no futuro veremos sao os elementos de um iterator).
para listas, tuplas, strings, e sets são seus elementos
para dicionarios sao as chaves
para gerar números no for
:
range
list(range(10))
list(range(2,10))
list(range(2,10,3))
for i in range(len(lista)):
list
converte o objeto para listas