Les listes en intention VS map() en Python
jeudi 4 octobre 2012 à 15:26Les adeptes de la programmation fonctionnelle connaissent bien le principe de la fonction map() et sont souvent plus à l’aise avec elle qu’avec les listes en intention en Python.
Les deux font pourtant la même chose, tant et si bien que Python 3 voit . Ouuuups. Dérapage un-con-trollé de Sam.map()
retiré de ses built-in
C’est plutôt une nouvelle chose car dans un language orienté objet comme Python, il y a une subtile différence entre map()
et les comprehension lists. Quand on utilise une méthode plutôt qu’une fonction, map()
tue le duck tuping:
>>> l = [u' Le choix dans la date ', ' Les nouilles cuisent au jus de canne '] >>> map(str.strip, l) Traceback (most recent call last): File "<ipython-input-14-41df8a735feb>", line 1, in <module> map(str.strip, l) TypeError: descriptor 'strip' requires a 'str' object but received a 'unicode' >>> map(unicode.strip, l) Traceback (most recent call last): File "<ipython-input-15-fc0fc8fef32d>", line 1, in <module> map(unicode.strip, l) TypeError: descriptor 'strip' requires a 'unicode' object but received a 'str' >>> [x.strip() for x in l] [u'Le choix dans la date', 'Les nouilles cuisent au jus de canne']
Notez que je vous recomande d’éviter à tout prix de mélanger des chaînes encodées, et des chaînes unicode, de toute façon. J’utilise ceci uniquement parce que c’est un cas simple à comprendre.
Mais ici, le problème peut être résumé ainsi: nous avons une collection hétérogène d’objets (qui pourraient être de n’importe quels autres types, il y a des cas beaucoup plus légitimes), et nous appliquons la méthode de l’objet. Qui ne correspond pas forcément à son type.
Avoir des types différents avec la même interface est courant en Python pour profiter du duck typing, donc ce genre de chose n’est pas un edge case.
La solution est bien entendu de wrapper l’appel dans une fonction anonyme:
>>> map(lambda x: x.strip(), l) [u'Le choix dans la date', 'Les nouilles cuisent au jus de canne']
Mais à ce stade, [x.strip() for x in l]
est beaucoup plus lisible et rapide. Sans compter qu’il peut être transformé en générateur juste en changeant les []
en ()
.