Skip to content

3. Conceptos básicos de Python

Image

3.1. Script [bases_01]: operaciones básicas

El script [bases_01] presenta las primeras características de Python.


# ----------------------------------
def affiche(chaine):
    # muestra una cadena
    print("chaine=%s" % chaine)


# ----------------------------------
def affiche_type(variable):
    # muestra el tipo de variable
    print("type[%s]=%s" % (variable, type(variable)))


# ----------------------------------
def f1(param):
    # suma 10 a param
    return param + 10


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


# -------------------------------- programa principal ------------------------------------
# esto es un comentario
# variable utilizada sin haber sido declarada
nom = "dupont"

# una salida a pantalla
print("nom=%s" % nom)

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

# su número de elementos
n = len(liste)

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

# inicialización de 2 variables con una tupla
(chaine1, chaine2) = ("chaine1", "chaine2")

# concatenación de las dos cadenas
chaine3 = chaine1 + chaine2

# visualización del resultado
print("[%s,%s,%s]" % (chaine1, chaine2, chaine3))

# uso de una función
affiche(chaine1)

# el tipo de una variable puede ser conocido
affiche_type(n)
affiche_type(chaine1)
affiche_type(liste)

# el tipo de una variable puede cambiar durante la ejecución
n = "a changé"
affiche_type(n)

# una función puede devolver un resultado
res1 = f1(4)
print("res1=%s" % res1)

# una función puede devolver una lista de valores
(res1, res2, res3) = f2()
print("(res1,res2,res3)=[%s,%s,%s]" % (res1, res2, res3))

# se podrían haber almacenado estos valores en una variable
liste = f2()
for i in range(len(liste)):
    print("liste[%s]=%s" % (i, liste[i]))

# pruebas
for i in range(len(liste)):
    # solo muestra las cadenas
    if type(liste[i]) == "str":
        print("liste[%s]=%s" % (i, liste[i]))

# otras pruebas
for i in range(len(liste)):
    # solo muestra los números enteros mayores que 10
    if type(liste[i]) == "int" and liste[i] > 10:
        print("liste[%s]=%s" % (i, liste[i]))

# un bucle 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]  # suma = suma + lista[i]
    i += 1  # i = i + 1
print("somme=%s" % somme)
# fin del programa

Comentarios

  • línea 2: la palabra clave def define una función;
  • línea 2: la función recibe el parámetro [chaine]. No se especifica el tipo del parámetro. Python utiliza exclusivamente el paso por valor. Este varía según el dato:
    • para un tipo simple (número, booleano…), este valor es el valor encapsulado por el dato (4, True…);
    • para un tipo complejo (lista, clase…), este valor es la dirección del dato;
  • líneas 3-4: el contenido de la función. Está sangrado hacia la derecha una tabulación. Es esta sangría, junto con el carácter : de la instrucción def, la que define el contenido de la función. Esto se aplica a todas las instrucciones que tienen contenido: if, else, while, for, try, except;
  • línea 4: la sintaxis utilizada aquí es [print('text1%F1text2%F2…' % data1, data2)]:
    • los [%Fi] (aquí %s) son formatos de visualización:
    • %s (cadena): para una cadena de caracteres;
    • %d (decimal): para números enteros decimales con signo;
    • %f (float): formato decimal para números reales;
    • %e (exponencial): formato exponencial para un número real;
  • [data1, data2…] son las expresiones cuyo valor queremos mostrar:
    • [data1] se mostrará con el formato F1;
    • [data2] se mostrará con el formato F2;
  • línea 10: Python maneja internamente el tipo de las variables. Se puede conocer el tipo de una variable con la función type(variable), que devuelve una variable de tipo 'type'. La expresión '%s' % (type(variable)) es una cadena de caracteres que representa el tipo de la variable;
  • línea 25: el programa principal. Este suele aparecer (aunque no necesariamente) después de la definición de todas las funciones del script. Su contenido no está sangrado;
  • línea 28: en Python, no se declaran las variables. Python distingue entre mayúsculas y minúsculas. La variable Nom es diferente de la variable nom. Una cadena de caracteres puede estar entre comillas " o entre apóstrofos '. Por lo tanto, se puede escribir 'dupont' o "dupont";
  • línea 34: hay una diferencia entre una tupla (1,2,3) (fíjate en los paréntesis) y una lista [1,2,3] (fíjate en los corchetes). La tupla no es modificable, mientras que la lista sí lo es. En ambos casos, el elemento n.º i se denota como [i];
  • línea 40: range(n) es la tupla (0,1,2,…,n-1);
  • línea 41: se utiliza el formato %d para los números enteros con signo;
  • línea 74: len(var) es el número de elementos de la colección var (tupla, lista, diccionario…);
  • línea 84: la estructura [for in …] permite iterar sobre una estructura iterable. Las listas y las tuplas son elementos iterables;
  • línea 86: los demás operadores booleanos son or y not;
  • línea 93: suma los números >0 de la lista;

Los resultados en pantalla son los siguientes:


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]: cadenas de formato

Python 3 introdujo una nueva forma de formatear cadenas de caracteres:


# cadenas de formato
# los formatos son los del lenguaje C
# entero
int1 = 10
print(f"[int1={int1}]")
print(f"[int1={int1:4d}]")
print(f"[int1={int1:04d}]")
# flotante
float1=8.2
print(f"[float1={float1}]")
print(f"[float1={float1:8.2f}]")
print(f"[float1={float1:.3e}]")
# cadena
str1="abcd"
print(f"[str1={str1}]")
print(f"[str1={str1:8s}]")
str2="jean de florette"
print(f"[{str2:20.10s}]")
# las cadenas formateadas se pueden asignar a variables
str3=f"[{str2:20.10s}]"
print(str3)

La sintaxis de la cadena formateada es la siguiente:

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

donde:

  • [expri]: una expresión;
  • [formati]: el formato de la expresión [expri]. Estos formatos son los del lenguaje C:
    • %d: para números enteros;
    • %f: notación decimal para los números reales;
    • %e: notación exponencial para los números reales;
    • %s: para cadenas de caracteres. Este es el formato que se utiliza cuando no se especifica ningún formato para [expri];
    • %nd, %nf, %ns: muestra [expri] en n caracteres: la cadena se trunca o se completa con espacios;
  • línea 7: [04d], entero de 4 caracteres completado a la izquierda con ceros;
  • línea 11: [8.2f], número real decimal de 8 caracteres, de los cuales 2 están después de la coma;
  • línea 12: [.3e], número real en forma exponencial con 3 decimales para la mantisa;
  • línea 18: [20.10s], los primeros 10 caracteres de una cadena completada con espacios hasta alcanzar 20 caracteres;

Los resultados de la ejecución son los siguientes:

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]: cambios de tipo

Aquí nos enfocamos en los cambios de tipo con datos de tipo str (cadena de caracteres), int (entero), float (numérico), bool (booleano).


# cambios 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))

# manejo de errores de conversión de tipo
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 los datos son instancias de clase y, como tales, tienen métodos
# cadena de caracteres
str1 = "abc"
print(str1.capitalize())
# número entero
int1 = 4
print(int1.bit_length())
# booleano
bool1=True
print(bool1.conjugate())
# número real
float1=8.2
print (float1.is_integer())

Son posibles numerosos cambios de tipo. Algunos pueden fallar, como el de las líneas 46-47, que intentan convertir la cadena «abc» en un número entero. Hemos manejado el error con una estructura try / except. La forma general de esta estructura

es la siguiente:


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

Si alguna de las acciones del bloque «try» genera una excepción (señala un error), se salta inmediatamente a la cláusula «except». Si las acciones del bloque «try» no generan ninguna excepción, se ignora la cláusula «except». Los atributos Exception y ex de la instrucción except son opcionales. Cuando están presentes, Exception especifica el tipo de excepción interceptada por la instrucción except y ex contiene la excepción que se produjo. Puede haber varias instrucciones except, si se desea manejar diferentes tipos de excepciones en el mismo try.

La instrucción finally es opcional. Si está presente, las acciones de la instrucción finally siempre se ejecutan, independientemente de si hubo una excepción o no.

Volveremos a hablar de las excepciones más adelante.

Las líneas 49-61 muestran diversos intentos de convertir datos de tipo str, int, float y NoneType en valores booleanos. Esto siempre es posible. Las reglas son las siguientes:

  • bool(int i) es igual a False si i es igual a 0, y a True en todos los demás casos;
  • bool(float f) es igual a False si f es igual a 0.0, y a True en todos los demás casos;
  • bool(str cadena) es igual a False si cadena tiene 0 caracteres, y a True en todos los demás casos;
  • bool(None) es False. None es un valor especial que significa que la variable existe pero no tiene valor.

Los resultados en pantalla son los siguientes:

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

Cabe señalar que todos los datos son objetos, es decir, instancias de clase. Esto significa que pueden tener métodos. Así lo muestran las líneas 63 a 75 del código. Aquí no pretendemos explicar qué hacen los métodos utilizados, sino simplemente mostrar que existen.

3.4. Script [bases_04]: ámbito de las variables

El script [bases_04] muestra que Python no cuenta con el concepto de variable de ámbito de bloque:


# alcance de las variables
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

Comentarios

Los resultados muestran dos cosas:

  • línea 4: la variable [i] del bloque [if] es la misma que la variable i utilizada en la línea 2;
  • línea 6: la variable [j] es la que se inicializó en el bloque [if];

En algunos lenguajes, en los que se declaran las variables, una variable definida en un bloque (como el de las líneas 3 a 5) no es conocida fuera de él. En Python, no ocurre nada de eso.

3.5. Script [bases_05]: listas - 1

El script [bases_05] es el siguiente:


# listas unidimensionales
# inicialización
list1 = [0, 1, 2, 3, 4, 5]

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

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

# agregar dos elementos
list1[len(list1):] = [10, 11]
# el formato %s permite mostrar la lista en una sola línea
print("%s" % list1)

# eliminación de los dos últimos elementos
list1[len(list1) - 2:] = []
# el formato predeterminado permite mostrar la lista en una sola línea
print(f"{list1}")

# Agregación de una lista al inicio de la lista
list1[:0] = [-10, -11, -12]
print(f"{list1}")

# inserción de dos elementos en el medio de la lista
list1[3:3] = [100, 101]
print(f"{list1}")

# eliminación de dos elementos en el medio de la lista
list1[3:4] = []
print(f"{list1}")

Notas:

  • la notación matriz[i:j] se refiere a los elementos del i al j-1 de la matriz;
  • la notación [i:] se refiere a los elementos i y siguientes de la matriz;
  • la notación [:i] se refiere a los elementos del 0 al i-1 de la matriz;
  • línea 19: print (%s) % (list1) muestra la cadena de caracteres: «[ list1[0], list1[2]…, list1[n-1]]»;
  • línea 24: la notación print ('f{list1}') hace lo mismo;

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

El código anterior se puede escribir de otra manera (bases_06) utilizando ciertos métodos de las listas:


# listas unidimensionales

# inicialización
list1 = [0, 1, 2, 3, 4, 5]

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

# modificación de un elemento
list1[1] = 10

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

# agregación de dos elementos
list1.extend([10, 11])
print(f"{list1}")

# eliminación de los dos últimos elementos
del list1[len(list1) - 2:]
print(f"{list1}")

# agregar una tupla al inicio de la lista
for i in (-12, -11, -10):
    list1.insert(0, i)
print(f"{list1}")

# inserción en el medio de la lista
for i in (101, 100):
    list1.insert(3, i)
print(f"{list1}")

# eliminación en el medio de la lista
del list1[3:4]
print(f"{list1}")

Los resultados obtenidos son los mismos que con la versión anterior.

3.7. Script [bases_07]: el diccionario

El script [bases_07] muestra cómo definir y utilizar un diccionario, a veces llamado tabla asociativa.


# una función que verifica si la clave «marido» existe en el diccionario «cónyuges»
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
# un diccionario
conjoints = {"Pierre": "Gisèle", "Paul": "Virginie", "Jacques": "Lucette", "Jean": ""}

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

# lista de claves del diccionario
print("liste des clés-------------")
clés = conjoints.keys()
print(f"{clés}")

# lista de valores del diccionario
print("liste des valeurs------------")
valeurs = conjoints.values()
print(f"{valeurs}")

# búsqueda de una clave
existe(conjoints, "Jacques")
existe(conjoints, "Lucette")
existe(conjoints, "Jean")

# eliminación de una clave-valor
del (conjoints["Jean"])
print(f"Nombre d'éléments du dictionnaire : {len(conjoints)}")
print(f"{conjoints}")

# las claves y los valores de un diccionario no son listas
print(f"type des clés : {type(clés)}")
print(f"type des valeurs : {type(valeurs)}")

# se pueden convertir en 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:

  • línea 11: la definición fija de un diccionario;
  • línea 15: conjoints.items() devuelve la lista de pares (clave, valor) del diccionario como conjuntos;
  • línea 20: conjoints.keys() devuelve las claves del diccionario de pares;
  • línea 25: conjoints.values() devuelve los valores del diccionario «conjuntos»;
  • línea 3: «marido» en «conjuntos» devuelve True si la clave mari existe en el diccionario conjoints; de lo contrario, devuelve False;
  • línea 36: un diccionario se puede mostrar en una sola línea.

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:

  • Cabe señalar en las líneas 16 y 17 de los resultados que las claves y los valores de un diccionario no forman una lista, sino un tipo «dict_keys»;
  • líneas 18 y 19: un simple cambio de tipo permite convertirlas a un tipo [list];

3.8. script [bases_08]: las tuplas

La tupla tiene similitudes con la lista, pero no es modificable:


# tuplas
# inicialización
tuple1 = (0, 1, 2, 3, 4, 5)

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

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

# un tuplo se puede mostrar en una sola línea
print(f"tuple1={tuple1}")

# una tupla no se puede modificar
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:

  • las líneas 17 a 20 de los resultados: muestran que una tupla no se puede modificar.

3.9. Script [bases_09]: listas y diccionarios multidimensionales

El script [bases_09] muestra cómo definir y utilizar una lista o un diccionario multidimensional:


# listas multidimensionales
# inicialización
multi = [[0, 1, 2], [10, 11, 12, 13], [20, 21, 22, 23, 24]]

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

# visualización en una sola línea
print(f"multi={multi}")

# diccionarios multidimensionales
# inicialización
multi = {"zéro": [0, 1], "un": [10, 11, 12, 13], "deux": [20, 21, 22, 23, 24]}

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

# visualización en una línea
print(f"multi={multi}")

Comentarios

  • línea 7: multi[i1] es una lista;
  • línea 18: «valor» es una 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]: vínculos entre cadenas y listas

El script [bases_10] muestra cómo recuperar en una lista los elementos de una cadena separados por un mismo separador.


# cadena a lista
chaine = '1:2:3:4'
liste = chaine.split(':')
print(type(liste))

# visualización de lista
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

# de lista a cadena
chaine2 = ":".join(liste)
print(f"chaine2={chaine2}")

# agregamos un campo vacío
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

# visualización de lista
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

# agregamos nuevamente un campo vacío
chaine += ":"
print(f"chaine={chaine}")
liste = chaine.split(":")

# visualización de lista
print(f"liste a {len(liste)} éléments")
print(f"liste={liste}")

Notas:

  • línea 3: el método chaine.split(separador) divide la cadena de caracteres chaine en elementos separados por séparateur y los devuelve en forma de lista. Por lo tanto, la expresión '1:2:3:4'.split(":") tiene como valor la lista ('1','2','3','4');
  • línea 11: 'separador'.join(lista) tiene como valor la cadena 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]: expresiones regulares

El script [bases_11] muestra cómo utilizar expresiones regulares:


# importamos el módulo de expresiones regulares
import re


# --------------------------------------------------------------------------
def compare(modèle, chaine):
    # compara la cadena [chaîne] con el patrón [modèle]
    # visualización de 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}]")


# expresiones regulares en Python
# extraer los distintos campos de una cadena
# el patrón: una secuencia de números rodeada de caracteres cualquiera
# solo queremos extraer la secuencia de números
modèle = r"^.*?(\d+).*?$"

# comparamos la cadena con el patrón
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

# el patrón: una secuencia de números rodeada de caracteres cualquiera
# se quiere la secuencia de números, así como los campos que la preceden y la siguen
modèle = r"^(.*?)(\d+)(.*?)$"

# comparamos la cadena con el patrón
compare(modèle, "xyz1234abcd")
compare(modèle, "12 34")
compare(modèle, "abcd")

# el patrón: una fecha en 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")

# el patrón: un 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")
# fin

Notas:

  • fíjate en el módulo [re] importado en la línea 2. Este es el que contiene las funciones para manejar las expresiones regulares;
  • línea 10: la comparación de una cadena con una expresión regular (patrón) devuelve el valor booleano True si la cadena coincide con el patrón, y False en caso contrario;
  • línea 12: match.groups() es una tupla cuyos elementos son las partes de la cadena que coinciden con los elementos de la expresión regular entre paréntesis. En el patrón:
    • ^.*?(\d+).*?, match.groups() será una tupla de un elemento porque hay un paréntesis;
    • ^(.*?)(\d+)(.*?)$, match.groups() será una tupla de tres elementos porque hay tres paréntesis;
  • línea 21: una expresión regular literal se escribe como r"xxx". Es el símbolo r el que convierte la cadena en una expresión regular;

Las expresiones regulares nos permiten verificar el formato de una cadena de caracteres. Así, podemos comprobar que una cadena que representa una fecha esté en el formato dd/mm/aa. Para ello, se utiliza un patrón y se compara la cadena con ese patrón. Por lo tanto, en este ejemplo, d, m y a deben ser números. El patrón de un formato de fecha válido es, entonces, "\d\d/\d\d/\d\d", donde el símbolo \d representa un dígito. Los símbolos que se pueden utilizar en un patrón son los siguientes:

Carácter
Descripción
\
Indica que el carácter siguiente es un carácter especial o literal. Por ejemplo, «n» corresponde al carácter «n», mientras que «\n» corresponde a un carácter de nueva línea. La secuencia «\\» corresponde a «\», mientras que «\»( corresponde a «(».
^
Corresponde al inicio de la cadena.
$
Corresponde al final de la cadena.
*
Corresponde al carácter anterior, cero o más veces. Por lo tanto, «zo*» corresponde a «z» o a «zoo».
+
Corresponde al carácter anterior, una o más veces. Por lo tanto, «zo+» corresponde a «zoo», pero no a «z».
?
Corresponde al carácter anterior, cero o una vez. Por ejemplo, «a?ve?» corresponde a «ve» en «lever».
.
Corresponde a cualquier carácter único, excepto el carácter de línea nueva.
(plantilla)
Busca modèle y almacena la coincidencia. La subcadena correspondiente se puede extraer de la colección match.groups(). Para encontrar coincidencias con caracteres entre paréntesis ( ), usa "\(" o "\)".
x|y
Coincide tanto con x como con y. Por ejemplo, «z|foot» coincide con «z» o con «foot». «(z|f)oo» coincide con «zoo» o con «foo».
{n}
n es un número entero no negativo. Corresponde exactamente a n multiplicado por el carácter. Por ejemplo, «o{2}» no corresponde a la «o» en «Bob», sino a las dos primeras «o» en «fooooot».
{n,}
n es un número entero no negativo. Corresponde al menos a n veces el carácter. Por ejemplo, «o{2,}» no coincide con la «o» en «Bob», sino con todas las «o» en «fooooot». «o{1,}» equivale a «o+» y «o{0,}» equivale a «o*».
{n,m}
m y n son números enteros no negativos. Corresponde a un número de veces del carácter que va desde al menos n hasta, como máximo, m. Por ejemplo, «o{1,3}» corresponde a las tres primeras «o» en «foooooot» y «o{0,1}» equivale a «o?».
[xyz]
Conjunto de caracteres. Corresponde a uno de los caracteres indicados. Por ejemplo, «[abc]» corresponde a la «a» en «plat».
[^xyz]
Conjunto de caracteres negativo. Corresponde a cualquier carácter no indicado. Por ejemplo, «[^abc]» corresponde a la «p» en «plat».
[a-z]
Rango de caracteres. Corresponde a cualquier carácter dentro de la serie especificada. Por ejemplo, «[a-z]» corresponde a cualquier letra minúscula entre «a» y «z».
[^m-z]
Rango de caracteres negativo. Corresponde a cualquier carácter que no se encuentre en la serie especificada. Por ejemplo, «[^m-z]» corresponde a cualquier carácter que no se encuentre entre «m» y «z».
\b
Corresponde a un límite que representa una palabra; es decir, a la posición entre una palabra y un espacio. Por ejemplo, «er\b» corresponde a «er» en «lever», pero no a «er» en «verbe».
\B
Corresponde a un límite que no representa una palabra. «en*t\B» corresponde a «ent» en «bien entendu».
\d
Corresponde a un carácter que representa un número. Equivale a [0-9].
\D
Corresponde a un carácter que no representa un número. Equivale a [^0-9].
\f
Corresponde a un carácter de salto de página.
\n
Corresponde a un carácter de nueva línea.
\r
Equivale a un carácter de retorno de carro.
\s
Corresponde a cualquier espacio en blanco, incluyendo el espacio, la tabulación, el salto de página, etc. Equivale a «[ \f\n\r\t\v]».
\S
Corresponde a cualquier carácter de espacio no en blanco. Equivale a «[^ \f\n\r\t\v]».
\t
Corresponde a un carácter de tabulación.
\v
Corresponde a un carácter de tabulación vertical.
\w
Corresponde a cualquier carácter que represente una palabra e incluya un guión bajo. Equivale a «[A-Za-z0-9_]».
\W
Corresponde a cualquier carácter que no represente una palabra. Equivale a «[^A-Za-z0-9_]».
\num
Corresponde a num, donde num es un número entero positivo. Hace referencia a las coincidencias almacenadas. Por ejemplo, «(.)\1» corresponde a dos caracteres idénticos consecutivos.
\n
Corresponde a n, donde n es un valor de escape octal. Los valores de escape octales deben tener 1, 2 o 3 dígitos. Por ejemplo, tanto «\11» como «\011» corresponden a un carácter de tabulación. "\0011" equivale a "\001" y "1". Los valores de escape octales no deben exceder 256. Si lo hicieran, solo se tomarían en cuenta los dos primeros dígitos en la expresión. Permite utilizar los códigos ASCII en expresiones regulares.
\xn
Equivale a n, donde n es un valor de escape hexadecimal. Los valores de escape hexadecimales deben constar obligatoriamente de dos dígitos. Por ejemplo, "\x41" corresponde a "A". "\x041" equivale a "\x04" y "1". Permite utilizar los códigos ASCII en expresiones regulares.

Un elemento en una plantilla puede aparecer una o más veces. Veamos algunos ejemplos relacionados con el símbolo \d, que representa un dígito:

patrón
significado
\d
un dígito
\d?
0 o 1 dígito
\d*
0 o más dígitos
\d+
1 o más dígitos
\d{2}
2 dígitos
\d{3,}
al menos 3 dígitos
\d{5,7}
entre 5 y 7 dígitos

Imaginemos ahora el modelo capaz de describir el formato esperado para una cadena de caracteres:

cadena buscada
modelo
una fecha en formato dd/mm/aa
\d{2}/\d{2}/\d{2}
una hora en formato hh:mm:ss
\d{2}:\d{2}:\d{2}
un número entero sin signo
\d+
una secuencia de espacios que puede estar vacía
\s*
un número entero sin signo que puede ir precedido o seguido de espacios
\s*\d+\s*
un número entero que puede ser con signo y estar precedido o seguido de espacios
\s*[+|-]?\s*\d+\s*
un número real sin signo que puede ir precedido o seguido de espacios
\s*\d+(.\d*)?\s*
un número real que puede ser con signo y estar precedido o seguido de espacios
\s*[+-]?\s*\d+(.\d*)?\s*
una cadena que contenga la palabra «justo»
\bjusto\b

Se puede especificar dónde se busca el patrón en la cadena:

patrón
significado
^patrón
el patrón comienza la cadena
patrón$
el patrón termina la cadena
^patrón$
el patrón inicia y termina la cadena
patrón
el patrón se busca en toda la cadena, comenzando por el principio de esta.
cadena buscada
patrón
una cadena que termina con un signo de exclamación
!$
una cadena que termina con un punto
\.$
una cadena que comienza con la secuencia //
^//
una cadena que contiene solo una palabra, que puede ir seguida o precedida de espacios
^\s*\w+\s*$
una cadena que contenga dos palabras, que pueden ir precedidas o seguidas de espacios
^\s*\w+\s*\w+\s*$
una cadena que contenga la palabra «secreto»
\bsecret\b

Los subconjuntos de un patrón pueden «extraerse». De este modo, no solo se puede verificar que una cadena coincida con un patrón específico, sino que también se pueden extraer de esa cadena los elementos que corresponden a los subconjuntos del patrón que se han encerrado entre paréntesis. Así, si analizamos una cadena que contiene una fecha dd/mm/aa y queremos además extraer los elementos dd, mm y aa de esa fecha, utilizaremos el patrón (\d\d)/(\d\d)/(\d\d).

Resultados del 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