Tom Daluzeau
← Parcours Python
Python · leçon 3 / 5Ch. 1 · Bases12 minTerminée

Collections : list, tuple, dict, set

Choisir entre liste, tuple, dictionnaire et ensemble, lire une clé de dictionnaire de la bonne façon (crochets, get ou point) et parcourir une collection avec for, in et items().

Mis à jour le

Pourquoi on voit ça

Un seul serveur, ça tient dans deux variables. Un parc de serveurs, non. Il te faut des collections : des valeurs qui en contiennent d’autres.

En DevOps, tu en croises partout. Un inventaire, c’est une liste de serveurs. Un serveur, c’est un dictionnaire (name, env, port). Un fichier JSON ou une réponse d’API, c’est un mélange des deux. Savoir lire s["env"], s.get("owner", "-") et une boucle for est donc indispensable, au contrôle comme en projet.

Les quatre collections

Type Écriture Ce que c’est Exemple
list [ ] une suite ordonnée, modifiable ["web-1", "db-1"]
tuple ( ) une suite ordonnée, non modifiable ("web-1", 80)
dict {clé: valeur} des paires clé → valeur {"name": "web-1", "port": 80}
set { } sans deux-points des valeurs sans doublon {80, 443}

Pour reconnaître un dict d’un set : le dictionnaire a des deux-points entre clé et valeur. Attention, {} tout seul est un dictionnaire vide.

Liste

Une liste garde ses éléments dans l’ordre. On lit un élément par sa position, qui commence à 0.

servers = ["web-1", "db-1"]
print(servers[0])
print(len(servers))
servers.append("cache-1")
print(servers)
web-1
2
['web-1', 'db-1', 'cache-1']

Tuple

Un tuple se lit comme une liste, mais on ne peut pas le modifier. Il sert pour un petit groupe de valeurs qui vont ensemble, comme un nom et un port.

t = ("web-1", 80)
print(t[0])
t[0] = "db-1"
web-1
TypeError: 'tuple' object does not support item assignment

Set

Un set (ensemble) ne garde qu’un exemplaire de chaque valeur. Pratique pour savoir combien de valeurs différentes on a.

ports = {80, 443, 80}
print(len(ports))
2

Dictionnaire

Un dictionnaire associe une clé à une valeur. C’est la forme d’un serveur dans le fil rouge du cours :

s = {"name": "web-1", "env": "prod", "port": 80}
print(s["name"])
web-1
list : des cases numérotées 0 "web-1" 1 "db-1" 2 "cache-1" servers[0] vaut "web-1" la première position est 0, pas 1 dict : des cases clé → valeur "name" "web-1" "env" "prod" "port" 80 s["name"] vaut "web-1" on lit par la clé, pas par la position
Une liste se lit par la position (à partir de 0), un dictionnaire par la clé.

Lire une clé : crochets, get ou point

C’est le point le plus important de la leçon. Il y a trois écritures, et elles ne font pas la même chose.

Écriture Si la clé existe Si la clé manque À utiliser pour
s["owner"] la valeur KeyError un champ obligatoire
s.get("owner", "-") la valeur la valeur de secours "-" un champ facultatif
s.owner AttributeError AttributeError jamais pour une clé
s = {"name": "web-1", "env": "prod"}
print(s["name"])
print(s.get("owner", "-"))
print(s.get("owner"))
web-1
-
None

À retenir sur chacune :

  • Les crochets plantent, et c’est voulu. Un serveur sans name est une donnée cassée : autant le savoir tout de suite avec un KeyError: 'name'.
  • get ne plante jamais. Sans deuxième argument, le secours est None.
  • Le point ne lit pas les clés. Il donne accès aux outils du type dict : get, keys, items. Écrire s.env cherche un outil nommé env, qui n’existe pas.
s = {"env": "prod"}
print(s.env)
AttributeError: 'dict' object has no attribute 'env'

Ne confonds pas les deux erreurs : KeyError = clé absente avec des crochets ; AttributeError = point utilisé à la place des crochets.

les clés de s les outils de dict s["env"] "env" "prod" s.get("owner", "-") pas de clé owner "-" valeur de secours s.env get, keys, items AttributeError pas d'outil env
Crochets et get cherchent parmi les clés. Le point cherche parmi les outils du type dict.

Parcourir avec for

for fait un tour de boucle par élément. La variable après for prend chaque élément à son tour.

servers = ["web-1", "db-1"]
for name in servers:
    print(name)
web-1
db-1

Le cas le plus courant en DevOps est la liste de dictionnaires :

servers = [
    {"name": "web-1", "env": "prod"},
    {"name": "db-1", "env": "dev"},
]
for s in servers:
    if s["env"] == "prod":
        print(s["name"])
web-1

À chaque tour, s est un dictionnaire entier. On lit ses champs avec les crochets.

Parcourir un dictionnaire : les clés, ou items()

Un for directement sur un dictionnaire ne donne que ses clés. Pour avoir la clé et la valeur, utilise items().

s = {"name": "web-1", "port": 80}
for k in s:
    print(k)
for k, v in s.items():
    print(k, v)
name
port
name web-1
port 80

in : clé pour un dict, valeur pour une liste

in demande « est-ce que c’est dedans ? » et répond True ou False. Mais il ne cherche pas au même endroit selon la collection.

Collection in cherche… Exemple Résultat
liste une valeur 80 in [22, 80, 443] True
dict une clé "port" in {"port": 5432} True
dict (pas les valeurs) 5432 in {"port": 5432} False
list : in regarde les valeurs 22 80 443 80 in ports → True dict : in regarde les clés "name" "web-1" "port" 5432 "port" in s → True 5432 in s → False
in cherche une valeur dans une liste, mais seulement une clé dans un dictionnaire.

in sur un dictionnaire sert donc à vérifier qu’un champ existe avant de le lire :

s = {"name": "web-1"}
if "owner" in s:
    print(s["owner"])
else:
    print("pas de propriétaire")
pas de propriétaire

À retenir

  • [ ] liste (modifiable), ( ) tuple (non modifiable), {clé: valeur} dict, {valeurs} set (sans doublon).
  • s["k"] : champ obligatoire, KeyError si la clé manque.
  • s.get("k", secours) : champ facultatif, ne plante jamais.
  • s.k : AttributeError. Le point lit les outils du dict, pas ses clés.
  • for x in liste parcourt les valeurs ; for k in dict parcourt les clés ; for k, v in dict.items() donne les deux.
  • in cherche une valeur dans une liste, une clé dans un dict.

Entraînement

12 questions, dont 4 à compléter. Tu réponds, on passe à la suivante. La note arrive à la fin.

Cartes · 10

Réviser les cartes ici

Espace : retourner