Lorsque l'on programme, il y a des moments où l'on s'exclame : "Oh !" C'est le cas avec des codes qui traitent des logiques complexes de manière étonnamment concise et élégante, que l'on appelle des codes 'Pythonic'.

Aujourd'hui, je vais vous présenter trois extraits de code Pythonic qui nous ont tous émus. Ils sont simples mais puissants.


1. Le slicing de préfixe : la véritable valeur quand c'est 'dynamique'



Quand il faut extraire un chemin relatif en enlevant le chemin de base d'un fichier, on combine len() et le slicing de chaîne.

# Exemple 1
prefix = "/var/data/user/files"
p = "/var/data/user/files/report.txt"

if p.startswith(prefix):
    relative_path = p[len(prefix):]
    print(relative_path) 
    # /report.txt

A ce stade, cela semble identique à p[22:] (en utilisant directement le chiffre 22). Cependant, la véritable valeur de ce code apparaît lorsque le préfixe change de façon dynamique.

✅ La manière Pythonic (valeur mise en avant)

Imaginez devoir traiter des chemins de données de plusieurs utilisateurs.

def get_relative_path(full_path, user_name):
    # ⭐️ Le préfixe change dynamiquement selon user_name !
    prefix = f"/var/data/{user_name}/files"

    if full_path.startswith(prefix):
        # len() calcule toujours avec précision la longueur dynamique.
        # pour user1, c'est 22, pour long_user, c'est 29...
        return full_path[len(prefix):]

    return full_path

# 'user1' (longueur du préfixe 22)
path1 = "/var/data/user1/files/report.txt"
print(f"user1: {get_relative_path(path1, 'user1')}")

# 'long_user_name_2' (longueur du préfixe 29)
path2 = "/var/data/long_user_name_2/files/document.pdf"
print(f"user2: {get_relative_path(path2, 'long_user_name_2')}")

Résultat :

user1: /report.txt
user2: /document.pdf

😲 Point d'émotion

Le code ne dépend ni du _contenu_ du préfixe ni de sa _longueur fixe_. Il se base uniquement sur la longueur calculée en temps réel avec len() pour effectuer le slicing [N:].

C'est là une maintenance plus facile et un code robuste, bien différent du hardcoding comme p[22:].


2. Le 'swap magique' sans variable temporaire

Pour échanger les valeurs de deux variables, il n'est pas nécessaire d'utiliser une variable temporaire appelée temp.

✅ La manière Pythonic

a = 10
b = 20

# Echange à la manière de Python
a, b = b, a

print(f"a = {a}, b = {b}") 
# a = 20, b = 10

😲 Point d'émotion

Cela utilise l'emballage (Packing) et le déballage (Unpacking) de tuples.

  1. b, a : La valeur à droite du =, soit (20, 10), est .

  2. a, b = ... : Les valeurs de ce tuple sont 'déballées' et assignées respectivement aux variables a et b.

'Changer a et b en b et a' est exprimé de manière intentionnelle dans le code.


3. Boucle for en une ligne : la magie de la 'compréhension'



'Je veux prendre certaines données, sélectionner uniquement les éléments correspondant à une condition, les transformer, puis créer une nouvelle collection.'

Cette longue phrase se traduit souvent par 4 à 5 lignes de boucle for. Python condense ce processus en une ligne.

Dictionnaire : Inverser Clé et Valeur

Le même émerveillement d'un échange de variables se retrouve dans les dictionnaires, où l'on inverse k:v en v:k.

# Approche traditionnelle
my_dict = {'name': 'Alice', 'job': 'Engineer'}
inverted_dict = {}
for k, v in my_dict.items():
    inverted_dict[v] = k

✅ La manière Pythonic (Compréhension de dictionnaire)

my_dict = {'name': 'Alice', 'job': 'Engineer'}

# "On extrait k, v de my_dict pour créer un nouveau dict avec v:k"
inverted_dict = {v: k for k, v in my_dict.items()}

print(inverted_dict)
# {'Alice': 'name', 'Engineer': 'job'}

(Cependant, cette méthode nécessite que les valeurs soient uniques.)

Liste : Créer une nouvelle liste avec des éléments correspondant à une condition

Cette magie est souvent utilisée avec des listes. Créons une liste des carrés des nombres pairs entre 0 et 9.

# Approche traditionnelle
squares_of_evens = []
for i in range(10):
    if i % 2 == 0:
        squares_of_evens.append(i * i)

✅ La manière Pythonic (Compréhension de liste)

# "En parcourant i de 0 à 9 (for), si i est pair (if), générer i*i (what) dans une liste"
squares_of_evens = [i * i for i in range(10) if i % 2 == 0]

print(squares_of_evens)
# [0, 4, 16, 36, 64]

😲 Point d'émotion

La compréhension transforme le code en une déclaration sur 'ce que' vous voulez au lieu de longuement expliquer 'comment' le créer (comment : déclarer une liste vide, boucle, append ...).


Conclusion : Quand le code émouvra

Les trois extraits que nous avons examinés aujourd'hui ne sont pas de simples 'conseils de codage'.

Ils illustrent la philosophie de Python, qui se demande "Comment puis-je exprimer plus clairement, plus brièvement, et plus élégamment mes intentions ?"

Ils nous rappellent que le code peut transcender de simples instructions pour la machine et devenir une 'écriture' qui incarne la pensée du développeur, tout comme un texte bien écrit peut nous émouvoir, un code bien écrit peut aussi nous procurer cet instant 'Oh?'.

Puissiez-vous retrouver cette 'émotion Pythonic' dans votre code.