Skip to content

3. Noções básicas de Python

Image

3.1. Script [bases_01]: operações elementares

O script [bases_01] apresenta as primeiras características do Python.


# ----------------------------------
def affiche(chaine):
    # exibe uma cadeia de caracteres
    print("chaine=%s" % chaine)


# ----------------------------------
def affiche_type(variable):
    # exibe o tipo de variável
    print("type[%s]=%s" % (variable, type(variable)))


# ----------------------------------
def f1(param):
    # soma 10 ao parâmetro
    return param + 10


# ----------------------------------
def f2():
    # retorna uma tupla de 3 valores
    return "un", 0, 100


# -------------------------------- programa principal ------------------------------------
# isto é um comentário
# variável utilizada sem ter sido declarada
nom = "dupont"

# uma saída para o ecrã
print("nom=%s" % nom)

# uma lista com elementos de tipos diferentes
liste = ["un", "deux", 3, 4]

# o seu número de elementos
n = len(liste)

# um ciclo
for i in range(n):
    print("liste[%d]=%s" % (i, liste[i]))

# inicialização de duas variáveis com uma tupla
(chaine1, chaine2) = ("chaine1", "chaine2")

# concatenação das duas cadeias
chaine3 = chaine1 + chaine2

# exibição do resultado
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))

# utilização de uma função
affiche(chaine1)

# o tipo de uma variável pode ser conhecido
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)

# o tipo de uma variável pode mudar durante a execução
n = "a changé"
affiche_type(n)

# uma função pode devolver um resultado
res1 = f1(4)
print("res1=%s" % res1)

# uma função pode devolver uma lista de valores
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))

# esses valores poderiam ter sido armazenados numa variável
liste = f2()
for i in range(len(liste)):
    print("liste[%s]=%s" % (i, liste[i]))

# testes
for i in range(len(liste)):
    # apenas apresenta as cadeias de caracteres
    if type(liste[i]) == "str":
        print("liste[%s]=%s" % (i, liste[i]))

# outros testes
for i in range(len(liste)):
    # apenas apresenta os números inteiros >10
    if type(liste[i]) == "int" and liste[i] > 10:
        print("liste[%s]=%s" % (i, liste[i]))

# um ciclo while
liste = (8, 5, 0, -2, 3, 4)
i = 0
somme = 0
while i < len(liste) and liste[i] > 0:
    print("liste[%s]=%s" % (i, liste[i]))
    somme += liste[i]  # soma=soma+lista[i]
    i += 1  # i = i + 1
print("somme=%s" % somme)
# fim do programa

Comentários

  • linha 2: a palavra-chave def define uma função;
  • linha 2: a função recebe o parâmetro [chaine]. Não se indica o tipo do parâmetro. O Python utiliza exclusivamente a passagem por valor. Esta difere consoante o tipo de dados:
    • para um tipo simples (número, booleano…), este valor é o valor encapsulado pelo dado (4, True…);
    • para um tipo complexo (lista, classe…), este valor é a morada do dado;
  • linhas 3-4: o conteúdo da função. Está indentado à direita com uma tabulação. É esta indentação, associada ao caractere : da instrução def, que define o conteúdo da função. Isto aplica-se a todas as instruções com conteúdo: if, else, while, for, try, except;
  • linha 4: a sintaxe aqui utilizada é [print('text1%F1text2%F2…' % data1, data2)]:
    • os [%Fi] (aqui %s) são formatos de exibição:
    • %s (string): para uma cadeia de caracteres;
    • %d (decimal): para números inteiros decimais com sinal;
    • %f (float): formato decimal para números reais;
    • %e (exponencial): formato exponencial para um número real;
  • [data1, data2…] são as expressões cujo valor se pretende apresentar:
    • [data1] será apresentado com o formato F1;
    • [data2] será apresentada no formato F2;
  • linha 10: O Python gere internamente o tipo das variáveis. É possível saber o tipo de uma variável com a função type(variable), que devolve uma variável do tipo «type». A expressão «%s» % (type(variável)) é uma cadeia de caracteres que representa o tipo da variável;
  • linha 25: o programa principal. Este surge normalmente (mas não necessariamente) após a definição de todas as funções do script. O seu conteúdo não é indentado;
  • linha 28: em Python, não se declaram variáveis. O Python distingue maiúsculas de minúsculas. A variável Nom é diferente da variável nom. Uma cadeia de caracteres pode ser colocada entre aspas " ou apóstrofos '. Assim, pode-se escrever 'dupont' ou "dupont";
  • linha 34: existe uma diferença entre uma tupla (1,2,3) (repare nos parênteses) e uma lista [1,2,3] (repare nos colchetes). A tupla é imutável, ao passo que a lista é mutável. Em ambos os casos, o elemento n.º i é denotado por [i];
  • linha 40: range(n) é a tupla (0,1,2,…,n-1);
  • linha 41: o formato %d é utilizado para números inteiros com sinal;
  • linha 74: len(var) é o número de elementos da coleção var (tupla, lista, dicionário…);
  • linha 84: a estrutura [for in …] permite iterar sobre uma estrutura iterável. As listas e os tuplos são elementos iteráveis;
  • linha 86: os outros operadores booleanos são or e not;
  • linha 93: calcula a soma dos números >0 da lista;

Os resultados apresentados no ecrã são os seguintes:


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_01.py
nom=dupont
liste[0]=un
liste[1]=deux
liste[2]=3
liste[3]=4
[chaine1,chaine2,chaine1chaine2]
chaine=chaine1
type[4]=<class 'int'>
type[chaine1]=<class 'str'>
type[['un', 'deux', 3, 4]]=<class 'list'>
type[a changé]=<class 'str'>
res1=14
(res1,res2,res3)=[un,0,100]
liste[0]=un
liste[1]=0
liste[2]=100
liste[0]=8
liste[1]=5
somme=13

Process finished with exit code 0

3.2. Script [bases_02]: cadeias de formatação

O Python 3 introduziu uma nova forma de formatar cadeias de caracteres:


# cadeias de formatação
# os formatos são os da linguagem C
# inteiro
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
# flutuante
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
# cadeia de caracteres
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
# as cadeias formatadas podem ser atribuídas a variáveis
str3=f"[{str2:20.10s}]"
print(str3)

A sintaxe da cadeia formatada é a seguinte:

f'…{expr1:format1} …. {expr2:format2} ….'

onde:

  • [expri]: uma expressão;
  • [formati]: o formato da expressão [expri]. Estes formatos são os da linguagem C:
    • %d: para números inteiros;
    • %f: notação decimal para números reais;
    • %e: notação exponencial para números reais;
    • %s: para cadeias de caracteres. É o formato utilizado quando não é utilizado qualquer formato para [expri];
    • %nd, %nf, %ns: exibe [expri] em n caracteres: a cadeia de caracteres é truncada ou preenchida com espaços;
  • linha 7: [04d], número inteiro de 4 caracteres preenchido à esquerda com zeros;
  • linha 11: [8.2f], número real decimal com 8 caracteres, dos quais 2 após a vírgula;
  • linha 12: [.3e], número real na forma exponencial com 3 casas decimais para a mantissa;
  • linha 18: [20.10s], os primeiros 10 caracteres de uma cadeia preenchida com espaços para perfazer 20 caracteres;

Os resultados da execução são os seguintes:

C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_02.py
[int1=10]
[int1=  10]
[int1=0010]
[float1=8.2]
[float1=    8.20]
[float1=8.200e+00]
[str1=abcd]
[str1=abcd    ]
[jean de fl          ]
[jean de fl          ]

Process finished with exit code 0

3.3. Script [bases_03]: alterações de tipos

Aqui, estamos interessados nas conversões de tipos com dados do tipo str (cadeia de caracteres), int (inteiro), float (real) e bool (booleano).


# mudanças de tipo
# int --> str, float, bool
x = 4
print(x, type(x))
x = str(4)
print(x, type(x))
x = float(4)
print(x, type(x))
x = bool(4)
print(x, type(x))

# bool --> int, float, str
x = True
print(x, type(x))
x = int(True)
print(x, type(x))
x = float(True)
print(x, type(x))
x = str(True)
print(x, type(x))

# str --> int, float, bool
x = "4"
print(x, type(x))
x = int("4")
print(x, type(x))
x = float("4")
print(x, type(x))
x = bool("4")
print(x, type(x))

# float → str, int, bool
x = 4.32
print(x, type(x))
x = str(4.32)
print(x, type(x))
x = int(4.32)
print(x, type(x))
x = bool(4.32)
print(x, type(x))

# gestão de erros de conversão de tipos
try:
    x = int("abc")
    print(x, type(x))
except ValueError as erreur:
    print(erreur)

# casos diversos
x = bool("abc")
print(x, type(x))
x = bool("")
print(x, type(x))
x = bool(0)
print(x, type(x))
x = None
print(x, type(x))
x = bool(None)
print(x, type(x))
x = bool(0.0)
print(x, type(x))

# todos os dados são instâncias de classe e, como tal, possuem métodos
# cadeia de caracteres
str1 = "abc"
print(str1.capitalize())
# número inteiro
int1 = 4
print(int1.bit_length())
# booleano
bool1=True
print(bool1.conjugate())
# número real
float1=8.2
print (float1.is_integer())

São possíveis inúmeras conversões de tipo. Algumas podem falhar, como a das linhas 46-47, que tentam converter a cadeia «abc» num número inteiro. O erro foi tratado com uma estrutura try / except. A forma geral desta estrutura

é a seguinte:


try:
    actions
except Exception as ex:
    actions
finally:
    actions

Se uma das ações do try lançar uma exceção (sinalizar um erro), ocorre um salto imediato para a cláusula except. Se as ações do **try não lançarem uma exceção, a cláusula except é ignorada. Os atributos Exception e ex da instrução except são opcionais. Quando estão presentes, Exception especifica o tipo de exceção interceptada pela instrução except e ex contém a exceção que ocorreu. Podem existir várias instruções except, caso se pretenda gerir diferentes tipos de exceções no mesmo try.

A instrução finally é opcional. Se estiver presente, as ações da instrução finally são sempre executadas, independentemente de ter ocorrido ou não uma exceção.

Voltaremos a abordar as exceções um pouco mais adiante.

As linhas 49-61 mostram várias tentativas de converter dados dos tipos str, int, float e NoneType em valores booleanos. Isso é sempre possível. As regras são as seguintes:

  • bool(int i) vale False se i for 0, True em todos os outros casos;
  • bool(float f) é igual a False se f for igual a 0,0, e a True em todos os outros casos;
  • bool(str cadeia) é igual a False se cadeia tiver 0 caracteres, True em todos os outros casos;
  • bool(None) é igual a False. None é um valor especial que significa que a variável existe, mas não tem valor.

Os resultados no ecrã são os seguintes:

C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_03.py
4 <class 'int'>
4 <class 'str'>
4.0 <class 'float'>
True <class 'bool'>
True <class 'bool'>
1 <class 'int'>
1.0 <class 'float'>
True <class 'str'>
4 <class 'str'>
4 <class 'int'>
4.0 <class 'float'>
True <class 'bool'>
4.32 <class 'float'>
4.32 <class 'str'>
4 <class 'int'>
True <class 'bool'>
invalid literal for int() with base 10: 'abc'
True <class 'bool'>
False <class 'bool'>
False <class 'bool'>
None <class 'NoneType'>
False <class 'bool'>
False <class 'bool'>
Abc
3
1
False

Process finished with exit code 0

Note-se que todos os dados são objetos, ou seja, instâncias de classe. Isto significa que podem ter métodos. É o que mostram as linhas 63-75 do código. Não pretendemos aqui explicar o que fazem os métodos utilizados, mas simplesmente mostrar que existem.

3.4. Script [bases_04]: âmbito das variáveis

O script [bases_04] mostra que o Python não possui o conceito de variável com âmbito de bloco:


# âmbito das variáveis
i = 4
if True:
    i += 1
    j = 7
print(f"i={i}, j={j}")

Resultados

1
2
3
4
C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_04.py
i=5, j=7

Process finished with exit code 0

Comentários

Os resultados revelam duas coisas:

  • linha 4: a variável [i] do bloco [if] é a mesma que a variável i utilizada na linha 2;
  • linha 6: a variável [j] é a que foi inicializada no bloco [if];

Em algumas linguagens, nas quais as variáveis são declaradas, uma variável definida num bloco (como o das linhas 3-5) não é reconhecida fora desse bloco. Em Python, isso não acontece.

3.5. Script [bases_05]: listas - 1

O script [bases_05] é o seguinte:


# listas unidimensionais
# inicialização
list1 = [0, 1, 2, 3, 4, 5]

# iteração - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
    print(f"list1[{i}]={list1[i]}")

list1[1] = 10
# iteração - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
    print(element)

# adição de dois elementos
list1[len(list1):] = [10, 11]
# o formato %s permite apresentar a lista numa única linha
print("%s" % list1)

# remoção dos dois últimos elementos
list1[len(list1) - 2:] = []
# o formato predefinido permite apresentar a lista numa única linha
print(f"{list1}")

# adição de uma lista no início da lista
list1[:0] = [-10, -11, -12]
print(f"{list1}")

# inserção de dois elementos a meio da lista
list1[3:3] = [100, 101]
print(f"{list1}")

# remoção de dois elementos no meio da lista
list1[3:4] = []
print(f"{list1}")

Notas:

  • a notação matriz[i:j] designa os elementos de i a j-1 da matriz;
  • a notação [i:] designa os elementos i e seguintes da matriz;
  • a notação [:i] designa os elementos de 0 a i-1 da matriz;
  • linha 19: print (%s) % (list1) exibe a cadeia de caracteres: «[ list1[0], list1[2]…, list1[n-1]]»;
  • linha 24: a notação print ('f{list1}') faz o mesmo;

Resultados


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_05.py
list1 a 6 éléments
list1[0]=0
list1[1]=1
list1[2]=2
list1[3]=3
list1[4]=4
list1[5]=5
list1 a 6 éléments
0
10
2
3
4
5
[0, 10, 2, 3, 4, 5, 10, 11]
[0, 10, 2, 3, 4, 5]
[-10, -11, -12, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 100, 101, 0, 10, 2, 3, 4, 5]
[-10, -11, -12, 101, 0, 10, 2, 3, 4, 5]

Process finished with exit code 0

3.6. Script [bases_06]: listas - 2

O código anterior pode ser escrito de forma diferente (bases_06) utilizando alguns métodos das listas:


# listas unidimensionais

# inicialização
list1 = [0, 1, 2, 3, 4, 5]

# percurso - 1
print(f"list1 a {len(list1)} éléments")
for i in range(len(list1)):
    print(f"list1[{i}]={list1[i]}")

# alteração de um elemento
list1[1] = 10

# percurso - 2
print(f"list1 a {len(list1)} éléments")
for element in list1:
    print(element)

# adição de dois elementos
list1.extend([10, 11])
print(f"{list1}")

# eliminação dos dois últimos elementos
del list1[len(list1) - 2:]
print(f"{list1}")

# adição de um tuplo no início da lista
for i in (-12, -11, -10):
    list1.insert(0, i)
print(f"{list1}")

# inserção no meio da lista
for i in (101, 100):
    list1.insert(3, i)
print(f"{list1}")

# remoção no meio da lista
del list1[3:4]
print(f"{list1}")

Os resultados obtidos são os mesmos que com a versão anterior.

3.7. script [bases_07]: o dicionário

O script [bases_07] mostra como definir e utilizar um dicionário, por vezes denominado tabela associativa.


# uma função que verifica se a chave «mari» existe no dicionário «conjoints»
def existe(conjoints, mari):
    if mari in conjoints:
        print(f"La clé [{mari}] existe associée à la valeur [{conjoints[mari]}]")
    else:
        print(f"La clé [{mari}] n'existe pas")


# ----------------------------- Main
# um dicionário
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}

# percurso - 1
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
for (clé, valeur) in conjoints.items():
    print(f"conjoints[{clé}]={valeur}")

# lista de chaves do dicionário
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")

# lista de valores do dicionário
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")

# pesquisa de uma chave
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")

# eliminação de uma chave-valor
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")

# as chaves e os valores de um dicionário não são listas
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")

# é possível transformá-las em listas
lclés = list(clés)
print(f"clés : {type(lclés)}, {lclés}")
lvaleurs = list(valeurs)
print(f"valeurs : {type(lvaleurs)}, {lvaleurs}")

Notas:

  • linha 11: a definição estática de um dicionário;
  • linha 15: conjoints.items() torna a lista de pares (chave, valor) do dicionário conjuntos;
  • linha 20: conjoints.keys() devolve as chaves do dicionário de pares;
  • linha 25: conjoints.values() devolve os valores do dicionário «conjuntos»;
  • linha 3: «mari» em «conjoints» devolve True se a chave mari existir no dicionário conjoints; caso contrário, devolve False;
  • linha 36: um dicionário pode ser apresentado numa única linha.

Resultados


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_07.py
Nombre d'éléments du dictionnaire : 4
conjoints[Pierre]=Gisèle
conjoints[Paul]=Virginie
conjoints[Jacques]=Lucette
conjoints[Jean]=
liste des clés-------------
dict_keys(['Pierre', 'Paul', 'Jacques', 'Jean'])
liste des valeurs------------
dict_values(['Gisèle', 'Virginie', 'Lucette', ''])
La clé [Jacques] existe associée à la valeur [Lucette]
La clé [Lucette] n'existe pas
La clé [Jean] existe associée à la valeur []
Nombre d'éléments du dictionnaire : 3
{'Pierre': 'Gisèle', 'Paul': 'Virginie', 'Jacques': 'Lucette'}
type des clés : <class 'dict_keys'>
type des valeurs : <class 'dict_values'>
clés : <class 'list'>, ['Pierre', 'Paul', 'Jacques']
valeurs : <class 'list'>, ['Gisèle', 'Virginie', 'Lucette']

Process finished with exit code 0

Notas:

  • Note-se nas linhas 16-17 dos resultados que as chaves e os valores de um dicionário não formam uma lista, mas sim um tipo «dict_keys»;
  • linhas 18-19: uma simples alteração do tipo permite convertê-los num tipo [list];

3.8. script [bases_08]: as tuplas

A tupla tem semelhanças com a lista, mas não é modificável:


# tuplos
# inicialização
tuple1 = (0, 1, 2, 3, 4, 5)

# iteração - 1
print(f"tuple1 a {len(tuple1)} elements")
for i in range(len(tuple1)):
    print(f"tuple1[{i}]={tuple1[i]}")

# iteração - 2
print(f"tuple1 a {len(tuple1)} elements")
for element in tuple1:
    print(element)

# um tuplo pode ser apresentado numa linha
print(f"tuple1={tuple1}")

# um tuplo não pode ser alterado
tuple1[0] = 10

Resultados


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py
tuple1 a 6 elements
tuple1[0]=0
tuple1[1]=1
tuple1[2]=2
tuple1[3]=3
tuple1[4]=4
tuple1[5]=5
tuple1 a 6 elements
0
1
2
3
4
5
tuple1=(0, 1, 2, 3, 4, 5)
Traceback (most recent call last):
  File "C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_08.py", line 19, in <module>
    tuple1[0] = 10
TypeError: 'tuple' object does not support item assignment

Process finished with exit code 1

Notas:

  • linhas 17-20 dos resultados: mostram que um tuplo não pode ser alterado.

3.9. Script [bases_09]: listas e dicionários multidimensionais

O script [bases_09] mostra como definir e utilizar uma lista ou um dicionário multidimensional:


# listas multidimensionais
# inicialização
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]

# iteração
for i1 in range(len(multi)):
    for i2 in range(len(multi[i1])):
        print(f"multi[{i1}][{i2}]={multi[i1][i2]}")

# exibição numa única linha
print(f"multi={multi}")

# dicionários multidimensionais
# inicialização
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}

# navegação
for (clé, valeur) in multi.items():
    for i2 in range(len(valeur)):
        print(f"multi[{clé}][{i2}]={multi[clé][i2]}")

# exibição numa única linha
print(f"multi={multi}")

Comentários

  • linha 7: multi[i1] é uma lista;
  • linha 18: «valor» é uma lista;

Resultados


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_09.py
multi[0][0]=0
multi[0][1]=1
multi[0][2]=2
multi[1][0]=10
multi[1][1]=11
multi[1][2]=12
multi[1][3]=13
multi[2][0]=20
multi[2][1]=21
multi[2][2]=22
multi[2][3]=23
multi[2][4]=24
multi=[[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]
multi[zéro][0]=0
multi[zéro][1]=1
multi[un][0]=10
multi[un][1]=11
multi[un][2]=12
multi[un][3]=13
multi[deux][0]=20
multi[deux][1]=21
multi[deux][2]=22
multi[deux][3]=23
multi[deux][4]=24
multi={'zéro': [0, 1], 'un': [10, 11, 12, 13], 'deux': [20, 21, 22, 23, 24]}

Process finished with exit code 0

3.10. Script [bases_10]: ligações entre cadeias de caracteres e listas

O script [bases_10] mostra como recuperar, numa lista, os elementos de uma cadeia separados por um mesmo separador.


# conversão de cadeia de caracteres em lista
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))

# exibição de lista
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

# da lista para cadeia
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")

# adicionar um campo vazio
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

# exibição em lista
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

# vamos adicionar novamente um campo vazio
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

# exibição da lista
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

Notas:

  • linha 3: o método chaine.split(separador) divide a cadeia de caracteres chaine em elementos separados por séparateur e apresenta-os sob a forma de uma lista. Assim, a expressão '1:2:3:4'.split(":") tem como valor a lista ('1','2','3','4');
  • linha 11: «separador».join(lista) tem como valor a cadeia de caracteres «lista[0]+separador+lista[1]+separador+…».

Resultados


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_10.py
<class 'list'>
liste a 4 éléments
liste=['1', '2', '3', '4']
chaine2=1:2:3:4
chaine=1:2:3:4:
liste a 5 éléments
liste=['1', '2', '3', '4', '']
chaine=1:2:3:4::
liste a 6 éléments
liste=['1', '2', '3', '4', '', '']

Process finished with exit code 0

3.11. Script [bases_11]: as expressões regulares

O script [bases_11] mostra como utilizar expressões regulares:


# importamos o módulo de expressões regulares
import re


# --------------------------------------------------------------------------
def compare(modèle, chaine):
    # compara a cadeia [chaîne] com o modelo [modèle]
    # exibição dos resultados
    print(f"\nRésultats({chaine},{modèle})")
    match = re.match(modèle, chaine)
    if match:
        print(match.groups())
    else:
        print(f"La chaîne [{chaine}] ne correspond pas au modèle [{modèle}]")


# expressões regulares em Python
# recuperar os diferentes campos de uma cadeia
# o modelo: uma sequência de algarismos rodeada por caracteres quaisquer
# pretende-se recuperar apenas a sequência de números
modèle = r"^.*?(\d+).*?$"

# comparamos a cadeia com o padrão
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

# o padrão: uma sequência de números rodeada por caracteres quaisquer
# pretende-se a sequência de números, bem como os campos que a precedem e a seguem
modèle = r"^(.*?)(\d+)(.*?)$"

# comparamos a cadeia de caracteres com o modelo
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

# o modelo — uma data no formato dd/mm/aa
modèle = r"^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
compare(modèle, "10/05/97")
compare(modèle, " 04/04/01 ")
compare(modèle, "5/1/01")

# o modelo — um número decimal
modèle = r"^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$"
compare(modèle, "187.8")
compare(modèle, "-0.6")
compare(modèle, "4")
compare(modèle, ".6")
compare(modèle, "4.")
compare(modèle, " + 4")
# fim

Notas:

  • repare no módulo [re] importado na linha 2. É este módulo que contém as funções de gestão das expressões regulares;
  • linha 10: a comparação de uma cadeia de caracteres com uma expressão regular (padrão) devolve o valor booleano True se a cadeia corresponder ao padrão, e False caso contrário;
  • linha 12: match.groups() é uma tupla cujos elementos são as partes da cadeia que correspondem aos elementos da expressão regular entre parênteses. No padrão:
    • ^.*?(\d+).*?, match.groups() será uma tupla de um elemento, porque existe um parêntese;
    • ^(.*?)(\d+)(.*?)$, match.groups() será uma tupla de 3 elementos, porque há três parênteses;
  • linha 21: uma expressão regular literal é denotada por r"xxx". É o símbolo r que transforma a cadeia de caracteres numa expressão regular;

As expressões regulares permitem-nos verificar o formato de uma cadeia de caracteres. Assim, podemos verificar se uma cadeia que representa uma data está no formato dd/mm/aa. Para tal, utiliza-se um padrão e compara-se a cadeia com esse padrão. Assim, neste exemplo, j, m e a têm de ser algarismos. O modelo de um formato de data válido é, então, "\d\d/\d\d/\d\d", em que o símbolo \d designa um algarismo. Os símbolos que podem ser utilizados num modelo são os seguintes:

Caractere
Descrição
\
Indica que o caractere seguinte é um caractere especial ou literal. Por exemplo, «n» corresponde ao caractere «n», enquanto «\n» corresponde a um caractere de nova linha. A sequência «\\» corresponde a «\», enquanto «\»( corresponde a «(».
^
Corresponde ao início da cadeia.
$
Corresponde ao fim da cadeia.
*
Corresponde ao carácter anterior, zero ou mais vezes. Assim, «zo*» corresponde a «z» ou a «zoo».
+
Corresponde ao carácter anterior, uma ou mais vezes. Assim, «zo+» corresponde a «zoo», mas não a «z».
?
Corresponde ao carácter anterior, zero ou uma vez. Por exemplo, «a?ve?» corresponde a «ve» em «lever».
.
Corresponde a qualquer carácter único, exceto ao carácter de nova linha.
(modelo)
Procura o modèle e memoriza a correspondência. A subcadeia correspondente pode ser extraída da coleção match.groups(). Para encontrar correspondências com caracteres entre parênteses ( ), utilize "\(" ou "\)".
x|y
Corresponde tanto a x como a y. Por exemplo, «z|foot» corresponde a «z» ou a «foot». «(z|f)oo» corresponde a «zoo» ou a «foo».
{n}
n é um número inteiro não negativo. Corresponde exatamente a n vezes o carácter. Por exemplo, «o{2}» não corresponde a «o» em «Bob,», mas aos dois primeiros «o» em «fooooot».
{n,}
n é um número inteiro não negativo. Corresponde a, pelo menos, n vezes o carácter. Por exemplo, «o{2,}» não corresponde ao «o» em «Bob», mas a todos os «o» em «fooooot». «o{1,}» equivale a «o+» e «o{0,}» equivale a «o*».
{n,m}
m e n são números inteiros não negativos. Corresponde a, no mínimo, n e, no máximo, m vezes o carácter. Por exemplo, «o{1,3}» corresponde aos três primeiros «o» em «foooooot» e «o{0,1}» equivale a «o?».
[xyz]
Conjunto de caracteres. Corresponde a um dos caracteres indicados. Por exemplo, «[abc]» corresponde a «a» em «plat».
[^xyz]
Conjunto de caracteres negativo. Corresponde a qualquer caractere não indicado. Por exemplo, «[^abc]» corresponde a «p» em «plat».
[a-z]
Intervalo de caracteres. Corresponde a qualquer caractere da série especificada. Por exemplo, «[a-z]» corresponde a qualquer letra minúscula entre «a» e «z».
[^m-z]
Intervalo de caracteres negativo. Corresponde a qualquer caractere que não se encontre na série especificada. Por exemplo, «[^m-z]» corresponde a qualquer caractere que não se encontre entre «m» e «z».
\b
Corresponde a um delimitador que representa uma palavra, ou seja, à posição entre uma palavra e um espaço. Por exemplo, «er\b» corresponde a «er» em «lever», mas não a «er» em «verbe».
\B
Corresponde a um limite que não representa uma palavra. «en*t\B» corresponde a «ent» em «bien entendu».
\d
Corresponde a um carácter que representa um algarismo. É equivalente a [0-9].
\D
Corresponde a um carácter que não representa um algarismo. É equivalente a [^0-9].
\f
Corresponde a um carácter de salto de página.
\n
Corresponde a um carácter de nova linha.
\r
Corresponde a um carácter de retorno de carro.
\s
Corresponde a qualquer espaço em branco, incluindo espaço, tabulação, salto de página, etc. É equivalente a «[ \f\n\r\t\v]».
\S
Corresponde a qualquer caractere de espaço não em branco. Equivale a «[^ \f\n\r\t\v]».
\t
Corresponde a um carácter de tabulação.
\v
Corresponde a um carácter de tabulação vertical.
\w
Corresponde a qualquer carácter que represente uma palavra e inclua um sublinhado. É equivalente a «[A-Za-z0-9_]».
\W
Corresponde a qualquer carácter que não represente uma palavra. Equivale a «[^A-Za-z0-9_]».
\num
Corresponde a num, em que num é um número inteiro positivo. Refere-se às correspondências memorizadas. Por exemplo, «(.)\1» corresponde a dois caracteres idênticos consecutivos.
\n
Corresponde a n, em que n é um valor de escape octal. Os valores de escape octais devem ter 1, 2 ou 3 dígitos. Por exemplo, "\11" e "\011" correspondem ambos a um carácter de tabulação. "\0011" equivale a "\001" e "1". Os valores de escape octais não devem exceder 256. Se tal acontecer, apenas os dois primeiros dígitos serão considerados na expressão. Permite utilizar os códigos ASCII em expressões regulares.
\xn
Corresponde a n, em que n é um valor de escape hexadecimal. Os valores de escape hexadecimais têm de incluir obrigatoriamente dois dígitos. Por exemplo, «\x41» corresponde a «A». «\x041» equivale a «\x04» e «1». Permite utilizar os códigos ASCII em expressões regulares.

Um elemento num modelo pode estar presente uma ou mais vezes. Vejamos alguns exemplos relacionados com o símbolo \d, que representa um algarismo:

modelo
significado
\d
um algarismo
\d?
0 ou 1 dígito
\d*
0 ou mais dígitos
\d+
1 ou mais dígitos
\d{2}
2 algarismos
\d{3,}
pelo menos 3 algarismos
\d{5,7}
entre 5 e 7 dígitos

Imaginemos agora o modelo capaz de descrever o formato esperado para uma cadeia de caracteres:

cadeia procurada
modelo
uma data no formato dd/mm/aa
\d{2}/\d{2}/\d{2}
uma hora no formato hh:mm:ss
\d{2}:\d{2}:\d{2}
um número inteiro sem sinal
\d+
uma sequência de espaços, que pode estar vazia
\s*
um número inteiro sem sinal que pode ser precedido ou seguido de espaços
\s*\d+\s*
um número inteiro que pode ser com sinal e precedido ou seguido de espaços
\s*[+|-]?\s*\d+\s*
um número real sem sinal que pode ser precedido ou seguido de espaços
\s*\d+(.\d*)?\s*
um número real que pode ser com sinal e precedido ou seguido de espaços
\s*[+-]?\s*\d+(.\d*)?\s*
uma cadeia de caracteres que contenha a palavra «justo»
\bjusto\b

É possível especificar onde se procura o padrão na cadeia:

padrão
significado
^padrão
o padrão inicia a cadeia
padrão$
o modelo termina a cadeia
^padrão$
o modelo inicia e termina a cadeia
padrão
o padrão é procurado em toda a cadeia, começando pelo início da mesma.
cadeia procurada
padrão
uma cadeia que termina com um ponto de exclamação
!$
uma cadeia que termina com um ponto
\.$
uma cadeia que começa com a sequência //
^//
uma cadeia que contém apenas uma palavra, eventualmente seguida ou precedida de espaços
^\s*\w+\s*$
uma cadeia que contenha duas palavras, eventualmente seguidas ou precedidas de espaços
^\s*\w+\s*\w+\s*$
uma cadeia que contenha a palavra «secret»
\bsecret\b

Os subconjuntos de um modelo podem ser «recuperados». Assim, não só é possível verificar se uma cadeia corresponde a um modelo específico, como também é possível recuperar nessa cadeia os elementos correspondentes aos subconjuntos do modelo que foram colocados entre parênteses. Assim, se analisarmos uma cadeia de caracteres que contenha uma data dd/mm/aa e, além disso, quisermos extrair os elementos dd, mm e aa dessa data, utilizaremos o modelo (\d\d)/(\d\d)/(\d\d).

Resultados do script


C:\Data\st-2020\dev\python\cours-2020\python3-flask-2020\venv\Scripts\python.exe C:/Data/st-2020/dev/python/cours-2020/python3-flask-2020/bases/bases_11.py

Résultats(xyz1234abcd,^.*?(\d+).*?$)
('1234',)

Résultats(12 34,^.*?(\d+).*?$)
('12',)

Résultats(abcd,^.*?(\d+).*?$)
La chaîne [abcd] ne correspond pas au modèle [^.*?(\d+).*?$]

Résultats(xyz1234abcd,^(.*?)(\d+)(.*?)$)
('xyz', '1234', 'abcd')

Résultats(12 34,^(.*?)(\d+)(.*?)$)
('', '12', ' 34')

Résultats(abcd,^(.*?)(\d+)(.*?)$)
La chaîne [abcd] ne correspond pas au modèle [^(.*?)(\d+)(.*?)$]

Résultats(10/05/97,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('10', '05', '97')

Résultats( 04/04/01 ,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
('04', '04', '01')

Résultats(5/1/01,^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$)
La chaîne [5/1/01] ne correspond pas au modèle [^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$]

Résultats(187.8,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '187.8')

Résultats(-0.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('-', '0.6')

Résultats(4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4')

Résultats(.6,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '.6')

Résultats(4.,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('', '4.')

Résultats( + 4,^\s*([+-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$)
('+', '4')

Process finished with exit code 0