Analyse : Chasse aux émoticônes 🕵️‍♂️

Regardons la solution envoyée :

import re

def num_emojis(arg):
return sum([re.match("^[:;][~-]?[)D]$",i) is not None for i in arg])


Ça marche ? Oui. Laisser ça en production ? Non.

1️⃣ Péché d'allocation
Les crochets dans sum([ ... ]) signifient que Python va d'abord créer en mémoire une liste complète de True/False de la taille du tableau d'origine, et seulement ensuite la sommer. Si l'entrée est un journal de 10 millions de lignes, votre mémoire va exploser.
Enlevons les crochets — nous obtenons une expression génératrice. Mémoire O(1) au lieu de O(n).

2️⃣ Vérifications redondantes
La construction match(...) is not None a le droit d'exister, mais en Python on utilise la "véracité" (truthiness) des objets. De plus, nous voulons simplement compter le nombre de correspondances. Approche idiomatique : sum(1 for ... if ...)

3️⃣ Recompilation
L'appel à re.match dans la boucle à chaque itération force Python à consulter le cache des regex. Si les chaînes sont nombreuses, le motif doit être compilé une fois avant la boucle.

Jetons les déchets et écrivons ceci :
import re

# Compilation en dehors de la boucle
SMILEY_PATTERN = re.compile(r"^[:;][~-]?[)D]$")

def count_smileys(faces: list[str]) -> int:
return sum(1 for face in faces if SMILEY_PATTERN.match(face))


☝️Mais le problème principal de cette solution n'est pas la syntaxe.
Pourquoi avons-nous besoin de regex ici ?

Comptons : nous avons 2 types d'yeux, 3 types de nez (y compris l'absence) et 2 types de bouche.
Il existe exactement 12 émoticônes valides. Comme l'a écrit @archimage_wiz, au lieu d'exécuter une lourde machine à états de regex sur chaque ligne, il suffit de vérifier l'appartenance de la chaîne à un ensemble (set) précalculé.

La recherche dans un ensemble s'effectue en temps constant O(1) (c'est une table de hachage).

Solution saine :
from typing import List

VALID_SMILES = {
':)', ';)', ':-)', ';-)', ':~)', ';~)',
':D', ';D', ':-D', ';-D', ':~D', ';~D'
}

def num_emojis_pro(arr: List[str]) -> int:
return sum(s in VALID_SMILES for s in arr)


Ce code n'importe pas le module re, il est évident pour tout junior au premier coup d'œil, et sur de gros volumes de données, il écrasera les regex en vitesse d'exécution.

Les outils complexes, c'est cool. Mais savoir se contenter d'outils simples, c'est une compétence.

#algosobes