Comment tirer le maximum d'une ligne unique 🧠

Qu'en est-il du comptage des zéros ?

L'instinct de base de la plupart est d'écrire une compréhension de liste :
max([len(i) for i in s.split('1')])

Cela fonctionnera. Mais vous divisez d'abord la chaîne (créant une liste en mémoire), puis vous la parcourez pour créer une autre liste d'entiers, pour la donner à max(). Double consommation de mémoire pour rien.

Mais on peut aussi utiliser un générateur :
max((len(chunk) for chunk in s.split('1')))

Côté mémoire, c'est parfait — la liste intermédiaire des longueurs n'est pas créée. Mais en vitesse, les expressions génératrices dans les fonctions intégrées de Python sont plus lentes à cause du surcoût d'itération et des appels de fonctions au niveau du bytecode.

Et encore mieux :
max(map(len, s.split('1')))

On se débarrasse de la boucle Python. map est implémenté en C, il est paresseux, rapide, ne consomme pas de mémoire. La plupart s'arrêtent là, satisfaits.

Mais... ce n'est pas encore optimal. Posez-vous la question : pourquoi calculer les longueurs de tous les morceaux avant de trouver le maximum ?

Les chaînes en Python se comparent lexicographiquement. Caractère par caractère. Par conséquent, la chaîne "000" est toujours plus grande que "00". Nous n'avons pas du tout besoin de calculer les longueurs des sous-chaînes pour les comparer.

Il faut faire comme ça !
len(max(s.split('1')))


Pourquoi est-ce la meilleure solution ? 🤔
1. L'appel s.split('1') renvoie immédiatement une liste de chaînes.
2. max() avale cette liste et compare les chaînes elles-mêmes au niveau C. Pas de map, pas d'appels à len pour chaque élément, pas d'appels de fonctions dans une boucle.
3. On appelle len() exactement une fois — sur la chaîne gagnante.

Moins de mouvements de l'interpréteur = code plus rapide.

#algosobes