banniere.png

Le module itertools

J'ai le map bien trop bas, j'ai l'filter qui s'dilate...


Ca fait maintenant plusieurs années que Guido parle de supprimer map(), filter(), reduce(), etc.. du langage, ce qui arrivera un jour puisque 50% de la communauté est en faveur de ce retrait, 25% contre et 25% sans opinions. lambda suivra probablement même chemin.

Mais que reste-t-il aux développeurs qui usent et abusent de ces primitives pour faire de la programmation fonctionnelle ?

... roulement de tambours ...

itertools ! qui offre des utilitaires de création d'itérateurs.

Iterators ? Generators ? Yield ?


itertools regroupe des fonctions de génération d'itérateurs, ces objets renvoyés par des generators, basés sur la directive yield, qui permet de sauvegarder des états d'exécution de la fonction.

-> Plus d'infos sur yield dans le manuel de référence

Un exemple typique de l'utilisation des generators, est l'implémentation de la suite de Fibonnaci:
def fibonnaci():
    x = 0
    y = 1 
    while 1: 
        x, y = y, x + y 
        yield x
Cette fonction renvoie un itérateur sans fin, qui permet de parcourir la suite:
>>> def fibonnaci():
...     x = 0
...     y = 1 
...     while 1: 
...         x, y = y, x + y 
...         yield x 
... 
>>> my_fib = fibonnaci() 
>>> my_fib.next() 
1 
>>> my_fib.next() 
1 
>>> my_fib.next() 
2 
>>> my_fib.next() 
3 
Ce principe peut être utilisé pour implémenter tout type de besoin, et à fortiori remplacer map(), filter(), reduce() et zip().

Contenu d'itertools


  • chain(*iterables): renvoie un iterator composé de tous les éléments fournis dans les iterables.                                                                
  • count([firstval]): Permet de retourner un iterator qui renvoie des entiers incrémentés par pas de 1. Si firstval est fourni, il est le premier entier renvoyé. Sinon count() utilise 0.                                                        
  • cycle(iterable): Renvoie un iterator qui permet de parcourir indéfiniment les éléments de l'itérable.                                                          
  • groupby(iterable[, keyfunc]): Renvoie un iterator qui permet de récupérer des couples (clé, groupe). keyfunc est une fonction qui doit renvoyer la clé pour l'élément courant. groupe est un itérable qui réunit les éléments regroupés par clé.
  • ifilter(predicate, iterable): Permet de renvoyer un iterator qui contient les éléments de l'itérable fourni, lorsque le callable predicate renvoie vrai. Si predicate vaut None, les valeurs sont testées avec bool().
  • imap(function, *iterables): Renvoie un iterator qui appelle function avec les éléments des itérables fournis, concaténés pour former la liste des paramètres. Si function vaut None, renvoie les paramètres préparés.
  • islice(iterable, [start,] stop [, step]): Permet de renvoyer un itérable qui est une sous-séquence de l'itérable fourni. start, stop et step s'utilisent comme les tranches.
  • izip(*iterables): Fonctionne comme zip(), pour agréger les éléments des itérables fournis.
  • repeat(element, times): Génère un iterator qui répète element times fois. Si times n'est pas fourni, devient un iterator infini qui renvoie toujours element.
  • starmap(function, sequence): Comparable à imap() mais le deuxième argument doit être une séquence de tuples. À chaque itération n, l'iterator renvoie le résultat de function(*sequence[n]).
  • takewhile(predicate, iterable): Renvoie les éléments de iterable tant que predicate(element) renvoie True.
  • tee(iterable[, n=2]): Découpe iterable en n itérables, renvoyés sous la forme d'un tuple. Chaque itérable renvoie ensuite les éléments de iterable.

Toutes ces fonctions peuvent être combinées, pour obtenir des mécanismes très puissants.

A chaque fois que vous vous apprêter à ajouter un appel à map(), zip() et consort, allez plutôt faire un tour du coté d'itertools...




Vous aimez ce post ? partagez-le :


Trackback URL | Categories: coding 0 comments - add

Tarek Ziadé. Copyright 2006. Tous droits réservés. Licence contenu site
BuzTrucs
Add to Technorati Favorites