Skip to content

3. Noções básicas de Python

Image

3.1. Script [bases_01]: Operações básicas

O script [bases_01] apresenta as funcionalidades básicas do Python.

# ----------------------------------
def affiche(chaine):
    #  chain poster
    print("chaine=%s" % chaine)


# ----------------------------------
def affiche_type(variable):
    #  displays variable type
    print("type[%s]=%s" % (variable, type(variable)))


# ----------------------------------
def f1(param):
    #  adds 10 to param
    return param + 10


# ----------------------------------
def f2():
    #  returns a tuple of 3 values
    return "un", 0, 100


#  -------------------------------- main program ------------------------------------
#  this is a comment
#  variable used without being declared
nom = "dupont"

#  a screen display
print("nom=%s" % nom)

#  a list with elements of different types
liste = ["un", "deux", 3, 4]

#  its number of elements
n = len(liste)

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

#  initialize 2 variables with a tuple
(chaine1, chaine2) = ("chaine1", "chaine2")

#  concatenation of the 2 strings
chaine3 = chaine1 + chaine2

#  result display
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))

#  use function
affiche(chaine1)

#  the type of a variable can be known
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)

#  the type of a variable can change at runtime
n = "a changé"
affiche_type(n)

#  a function can return a result
res1 = f1(4)
print("res1=%s" % res1)

#  a function can return a list of values
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))

#  we could have retrieved these values in a
liste = f2()
for i in range(len(liste)):
    print("liste[%s]=%s" % (i, liste[i]))

#  testing
for i in range(len(liste)):
    #  displays only channels
    if type(liste[i]) == "str":
        print("liste[%s]=%s" % (i, liste[i]))

#  other tests
for i in range(len(liste)):
    #  displays only integers >10
    if type(liste[i]) == "int" and liste[i] > 10:
        print("liste[%s]=%s" % (i, liste[i]))

#  a while loop
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]  #  sum=sum+list[i]
    i += 1  #  i=i+1
print("somme=%s" % somme)
#  end of program

Comentários

  • linha 2: a palavra-chave def define uma função;
  • linha 2: a função recebe o parâmetro [string]. O tipo do parâmetro não é especificado. O Python utiliza exclusivamente a passagem por valor. Isto varia consoante os dados:
    • para um tipo simples (número, booleano, etc.), este valor é o valor encapsulado pelos dados (4, True, etc.);
    • para um tipo complexo (lista, classe, etc.), este valor é o endereço dos dados;
  • linhas 3–4: o corpo da função. Está recuado uma tabulação para a direita. É este recuo, combinado com o caractere : da instrução def, que define o corpo da função. Isto aplica-se a todas as instruções com um corpo: if, else, while, for, try, except;
  • linha 4: a sintaxe utilizada aqui é [print('text1%F1text2%F2…' % data1, data2)]:
    • os [%Fi] (aqui %s) são formatos de exibição:
    • %s (string): para uma string;
    • %d (decimal): para 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 cujos valores pretende apresentar:
    • [data1] será exibido utilizando o formato F1;
    • [data2] será exibido utilizando o formato F2;
  • linha 10: O Python gere os tipos de variáveis internamente. Pode determinar o tipo de uma variável utilizando a função type(variável), 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 está indentado;
  • linha 28: Em Python, as variáveis não são declaradas. 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 duplas " ou aspas simples '. Por isso, pode 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). Uma tupla é imutável, enquanto uma lista é mutável. Em ambos os casos, o elemento número i é denotado como [i];
  • Linha 40: range(n) é a tupla (0, 1, 2, …, n-1);
  • linha 41: o formato %d é utilizado para inteiros com sinal;
  • linha 74: len(var) é o número de elementos na coleção var (tupla, lista, dicionário, etc.);
  • linha 84: a estrutura [for in …] permite iterar sobre uma estrutura iterável. Listas e tuplas são elementos iteráveis;
  • linha 86: os outros operadores booleanos são or e not;
  • linha 93: soma os números maiores que 0 na lista;

A saída no ecrã é a seguinte:


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]: Strings formatadas

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

#  formatting strings
#  formats are those of the C language
#  integer
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
#  float
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
#  string
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
#  formatted strings can be assigned to variables
str3=f"[{str2:20.10s}]"
print(str3)

A sintaxe da string formatada é a seguinte:

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

onde:

  • [expr]: 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. Este é o formato utilizado quando não é especificado nenhum formato para [expr];
    • %nd, %nf, %ns: exibe [expri] em n caracteres: a cadeia de caracteres é truncada ou preenchida com espaços;
  • linha 7: [04d], inteiro de 4 caracteres preenchido à esquerda com zeros;
  • linha 11: [8.2f], número de ponto flutuante decimal de 8 caracteres com 2 dígitos após a vírgula decimal;
  • linha 12: [.3e], um número de ponto flutuante na forma exponencial com 3 casas decimais para a mantissa;
  • linha 18: [20.10s], os primeiros 10 caracteres de uma cadeia preenchidos 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]: Conversões de tipos

Aqui, focamo-nos nas conversões de tipos que envolvem dados dos tipos str (string), int (inteiro), float (ponto flutuante) e bool (booleano).

#  type changes
#  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))

#  type change error handling
try:
    x = int("abc")
    print(x, type(x))
except ValueError as erreur:
    print(erreur)

#  various cases
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))

#  all data are class instances and as such have their own methods
#  character string
str1 = "abc"
print(str1.capitalize())
#  whole number
int1 = 4
print(int1.bit_length())
#  boolean
bool1=True
print(bool1.conjugate())
#  real number
float1=8.2
print (float1.is_integer())

São possíveis muitas conversões de tipo. Algumas podem falhar, como as das linhas 46–47, que tentam converter a cadeia de caracteres «abc» num inteiro. Tratámos o erro utilizando um bloco try/except. A forma geral deste bloco

é a seguinte:


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

Se alguma das ações no bloco try lançar uma exceção (sinalizar um erro), o controlo salta imediatamente para a cláusula except. Se as ações no bloco 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 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 se pretender tratar diferentes tipos de exceções dentro do mesmo bloco try.

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

Voltaremos às exceções um pouco mais tarde.

As linhas 49–61 mostram várias tentativas de converter dados dos tipos str, int, float e NoneType para boolean. Isto é sempre possível. As regras são as seguintes:

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

A saída no ecrã é a seguinte:

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 que todos os dados são objetos, ou seja, instâncias de classes. Isto significa que podem ter métodos. Isto é demonstrado nas linhas 63–75 do código. Não estamos aqui a tentar explicar o que os métodos fazem, mas simplesmente a 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áveis com âmbito de bloco:

1
2
3
4
5
6
#  variable scope
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 mostram duas coisas:

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

Em algumas linguagens, onde as variáveis são declaradas, uma variável definida dentro de um bloco (como a das linhas 3–5) não é conhecida fora dele. Em Python, isso não acontece.

3.5. Script [bases_05]: Listas - 1

O script [bases_05] é o seguinte:

#  1-dimensional lists
#  initialization
list1 = [0, 1, 2, 3, 4, 5]

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

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

#  addition of two elements
list1[len(list1):] = [10, 11]
#  the %s format displays the list on one line
print("%s" % list1)

#  deletion of last two items
list1[len(list1) - 2:] = []
#  the default format displays the list on one line
print(f"{list1}")

#  add to the beginning of a list
list1[:0] = [-10, -11, -12]
print(f"{list1}")

#  mid-list insertion of two elements
list1[3:3] = [100, 101]
print(f"{list1}")

#  deletion of two items in the middle of a list
list1[3:4] = []
print(f"{list1}")

Notas:

  • a notação array[i:j] refere-se aos elementos de i a j-1 da matriz;
  • a notação [i:] refere-se aos elementos i e aos elementos subsequentes da matriz;
  • a notação [:i] refere-se aos 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 determinados métodos de lista:

#  1-dimensional lists

#  initialization
list1 = [0, 1, 2, 3, 4, 5]

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

#  element modification
list1[1] = 10

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

#  addition of two elements
list1.extend([10, 11])
print(f"{list1}")

#  deletion of last two items
del list1[len(list1) - 2:]
print(f"{list1}")

#  add a tuple at the beginning of the list
for i in (-12, -11, -10):
    list1.insert(0, i)
print(f"{list1}")

#  mid-list insertion
for i in (101, 100):
    list1.insert(3, i)
print(f"{list1}")

#  mid-list deletion
del list1[3:4]
print(f"{list1}")

Os resultados são os mesmos da 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 chamado de matriz associativa.

#  a function that checks whether the husband key exists in the joint dictionary
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
#  a dictionary
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}

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

#  list of dictionary keys
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")

#  list of dictionary values
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")

#  key search
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")

#  deleting a key-value
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")

#  dictionary keys and values are not lists
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")

#  we can transform them into lists
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 codificada de um dicionário;
  • linha 15: conjoints.items() devolve a lista de pares (chave, valor) do dicionário conjoints;
  • linha 20: conjoints.keys() devolve as chaves do dicionário conjoints;
  • linha 25: conjoints.values() devolve os valores do dicionário conjoints;
  • linha 3: husband em spouses retorna True se a chave husband existir no dicionário spouses, False caso contrário;
  • 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 que nas linhas 16–17 dos resultados, 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 conversão de tipo converte-as para um tipo [lista];

3.8. script [bases_08]: tuplas

Uma tupla é semelhante a uma lista, mas é imutável:

#  tuples
#  initialization
tuple1 = (0, 1, 2, 3, 4, 5)

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

#  routes - 2
print(f"tuple1 a {len(tuple1)} elements")
for element in tuple1:
    print(element)

#  a tuble can be displayed in one line
print(f"tuple1={tuple1}")

#  a tuple cannot be modified
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:

  • As linhas 17–20 da saída: mostram que uma tupla não pode ser modificada.

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

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

#  multidimensional lists
#  initialization
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]

#  route
for i1 in range(len(multi)):
    for i2 in range(len(multi[i1])):
        print(f"multi[{i1}][{i2}]={multi[i1][i2]}")

#  one-line display
print(f"multi={multi}")

#  multidimensional dictionaries
#  initialization
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}

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

#  one-line display
print(f"multi={multi}")

Comentários

  • linha 7: multi[i1] é uma lista;
  • linha 18: value é 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] demonstra como extrair elementos de uma cadeia de caracteres, separados por um delimitador comum, para uma lista.

#  string to list
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))

#  list display
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

#  list to string
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")

#  add an empty field
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

#  list display
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

#  let's add another empty field
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

#  list display
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

Notas:

  • linha 3: o método string.split(separator) divide a string string em elementos separados pelo separador e devolve-os como uma lista. Assim, a expressão '1:2:3:4'.split(":") devolve a lista ('1','2','3','4');
  • linha 11: 'separator'.join(list) devolve a string 'list[0]+separator+list[1]+separator+…'.

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]: Expressões regulares

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

#  import the regular expressions module
import re


# --------------------------------------------------------------------------
def compare(modèle, chaine):
    #  compares the string [string] with the model [model]
    #  displaying results
    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}]")


#  regular expressions in python
#  retrieve the various fields of a string
#  the model: a sequence of numbers surrounded by any characters
#  you only want to retrieve the sequence of digits
modèle = r"^.*?(\d+).*?$"

#  the chain is compared with the
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

#  the model: a sequence of numbers surrounded by any characters
#  we want the sequence of numbers and the fields that follow and precede them
modèle = r"^(.*?)(\d+)(.*?)$"

#  the chain is compared with the
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

#  the template - a date in dd/mm/yy format
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")

#  the model - a decimal number
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")
#  end

Notas:

  • Repare no módulo [re] importado na linha 2. Este contém as funções para lidar com expressões regulares;
  • linha 10: a comparação de uma cadeia de caracteres com uma expressão regular (padrão) retorna 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 string que correspondem aos elementos da expressão regular entre parênteses. No padrão:
    • ^.*?(\d+).*?, match.groups() será uma tupla de um elemento, porque há um conjunto de parênteses;
    • ^(.*?)(\d+)(.*?)$, match.groups() será uma tupla de 3 elementos porque há três parênteses;
  • linha 21: uma expressão regular literal é escrita como r"xxx". É o símbolo r que transforma a cadeia de caracteres numa expressão regular;

As expressões regulares permitem-nos validar o formato de uma cadeia de caracteres. Por exemplo, podemos verificar se uma cadeia de caracteres que representa uma data está no formato dd/mm/aa. Para tal, utilizamos um padrão e comparamos a cadeia de caracteres com esse padrão. Neste exemplo, d, m e y devem ser dígitos. O padrão para um formato de data válido é, portanto, "\d\d/\d\d/\d\d", onde o símbolo \d representa um dígito. Os símbolos que podem ser usados num padrão são os seguintes:

Caractere
Descrição
\
Designa o caractere seguinte como 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 caractere anterior zero ou mais vezes. Assim, «zo*» corresponde a «z» ou «zoo».
+
Corresponde ao caractere anterior, uma ou mais vezes. Assim, «zo+» corresponde a «zoo», mas não a «z».
?
Corresponde ao caractere anterior zero ou uma vez. Por exemplo, "a?ve?" corresponde a "ve" em "lever".
.
Corresponde a qualquer caractere único, exceto o caractere de nova linha.
(padrão)
Procura o padrão e armazena a correspondência. A subcadeia correspondente pode ser recuperada da coleção match.groups(). Para encontrar correspondências com caracteres dentro de parênteses ( ), utilize "\(" ou "\)".
x|y
Corresponde a x ou 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 ocorrências do caractere. Por exemplo, "o{2}" não corresponde a "o" em "Bob", mas corresponde aos dois primeiros "o"s em "fooooot".
{n,}
n é um número inteiro não negativo. Corresponde a pelo menos n ocorrências do caractere. Por exemplo, "o{2,}" não corresponde a "o" em "Bob", mas corresponde a todos os "o"s em "fooooot". "o{1,}" é equivalente a "o+" e "o{0,}" é equivalente 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 ocorrências do caractere. Por exemplo, "o{1,3}" corresponde aos primeiros três "o"s em "foooooot" e "o{0,1}" é equivalente a "o?".
[xyz]
Conjunto de caracteres. Corresponde a qualquer um dos caracteres especificados. Por exemplo, "[abc]" corresponde a "a" em "plat".
[^xyz]
Conjunto de caracteres negativo. Corresponde a qualquer caractere não listado. Por exemplo, "[^abc]" corresponde a "p" em "plat".
[a-z]
Intervalo de caracteres. Corresponde a qualquer caractere no intervalo especificado. Por exemplo, "[a-z]" corresponde a qualquer caractere alfabético minúsculo entre "a" e "z".
[^m-z]
Intervalo de caracteres negativos. Corresponde a qualquer caractere que não esteja no intervalo especificado. Por exemplo, "[^m-z]" corresponde a qualquer caractere que não esteja entre "m" e "z".
\b
Corresponde a um limite de palavra, ou seja, a posição entre uma palavra e um espaço. Por exemplo, "er\b" corresponde a "er" em "lever", mas não a "er" em "verb".
\B
Corresponde a um limite que não representa uma palavra. "en*t\B" corresponde a "ent" em "bien entendu".
\d
Corresponde a um caractere que representa um dígito. Equivalente a [0-9].
\D
Corresponde a um caractere que não seja um dígito. Equivalente a [^0-9].
\f
Corresponde a um caractere de quebra de linha.
\n
Equivalente a um caractere de nova linha.
\r
Equivalente a um caractere de retorno do carro.
\s
Corresponde a qualquer espaço em branco, incluindo espaço, tabulação, quebra de página, etc. Equivalente a "[ \f\n\r\t\v]".
\S
Corresponde a qualquer caractere que não seja de espaço em branco. Equivalente a "[^ \f\n\r\t\v]".
\t
Corresponde a um caractere de tabulação.
\v
Corresponde a um caractere de tabulação vertical.
\w
Corresponde a qualquer caractere que represente uma palavra, incluindo o sublinhado. Equivalente a "[A-Za-z0-9_]".
\W
Corresponde a qualquer caractere que não represente uma palavra. Equivalente a "[^A-Za-z0-9_]".
\num
Corresponde a num, onde num é um número inteiro positivo. Refere-se a correspondências armazenadas. Por exemplo, "(.)\1" corresponde a dois caracteres idênticos consecutivos.
\n
Corresponde a n, onde n é um valor de escape octal. Os valores de escape octais devem consistir em 1, 2 ou 3 dígitos. Por exemplo, "\11" e "\011" correspondem ambos a um caractere de tabulação. "\0011" é equivalente a "\001" & "1". Os valores de escape octais não devem exceder 256. Se excederem, apenas os dois primeiros dígitos são tidos em conta na expressão. Permite que os códigos ASCII sejam utilizados em expressões regulares.
\xn
Corresponde a n, onde n é um valor de escape hexadecimal. Os valores de escape hexadecimais devem consistir em exatamente dois dígitos. Por exemplo, "\x41" corresponde a "A". "\x041" é equivalente a "\x04" e "1". Permite a utilização de códigos ASCII em expressões regulares.

Um elemento num padrão pode aparecer uma ou várias vezes. Vejamos alguns exemplos envolvendo o símbolo \d, que representa um único dígito:

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

Agora, imaginemos um modelo capaz de descrever o formato esperado para uma cadeia de caracteres:

cadeia de caracteres alvo
padrão
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 inteiro sem sinal
\d+
uma sequência de espaços, que pode estar vazia
\s*
um inteiro sem sinal que pode ser precedido ou seguido por espaços
\s*\d+\s*
um inteiro que pode ser assinado e precedido ou seguido por espaços
\s*[+|-]?\s*\d+\s*
um número real sem sinal que pode ser precedido ou seguido por espaços
\s*\d+(.\d*)?\s*
um número real que pode ser assinado e precedido ou seguido por espaços
\s*[+-]?\s*\d+(.\d*)?\s*
uma cadeia de caracteres que contenha a palavra «just»
\bjuste\b

Pode especificar onde procurar o padrão na cadeia de caracteres:

padrão
significado
^padrão
o padrão inicia a cadeia
padrão$
o padrão termina a cadeia
^padrão$
o padrão inicia e termina a cadeia
padrão
o padrão é procurado em qualquer parte da cadeia, começando pelo início.
Padrão procurado
padrão
uma cadeia que termine com um ponto de exclamação
!$
uma sequência que termina com um ponto
\.$
uma sequência que começa com //
^//
uma cadeia composta por uma única palavra, opcionalmente precedida ou seguida por espaços
^\s*\w+\s*$
uma cadeia composta por duas palavras, opcionalmente seguida ou precedida por espaços
^\s*\w+\s*\w+\s*$
uma cadeia que contém a palavra secret
\bsecret\b

Os subpadrões de um padrão podem ser «extraídos». Assim, não só podemos verificar se uma cadeia corresponde a um determinado padrão, como também podemos extrair dessa cadeia os elementos correspondentes aos subpadrões do padrão que foram colocados entre parênteses. Por exemplo, se analisarmos uma cadeia de caracteres que contenha uma data no formato dd/mm/aa e quisermos extrair os componentes dd, mm e aa dessa data, usaríamos o padrão (\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