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
CPython é a “padrão” (versão 3.10 lançada em Outubro 2021)
micropython - para sistemas embarcados https://micropython.org/
IronPython - para o .NET https://ironpython.net/
Jython - converte para bytecode do Java https://www.jython.org/
pypy - JIT compiler (compila so funcoes em metodos muito usados em tempo de execução) https://www.pypy.org/index.html
pypy normalmente esta de 1 a 2 números abaixo a subversão do CPython pypy3 está na versão 3.7
O ambiente de execução do CPython nao permite paralelismo (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 explicitamente criar codigo que explicitamente roda em threads (start/synchronize/etc) mas provavelmente ele não roda realmente em threads https://realpython.com/intro-to-python-threading/
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 da variável x
Brancos e mudança de linha como separador de comandos e indicador de blocos (como o haskell)
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
sorted(l) - retorna nova lista
del x[1] - remove - é um operador e não uma função (sem parênteses) ou metodos (sem ponto).
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
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
o 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