5.15.1 Funzioni di itertools

Tutte le seguenti funzioni del modulo costruiscono e restituiscono iteratori. Alcune forniscono flussi di lunghezza infinita, percui dovrebbero essere utilizzate solo da funzioni o cicli che troncano il flusso.

chain( *iterables)
Crea un iteratore che restituisce elementi dalla prima sequenza iterabile passata per parametro fino al suo esaurimento, poi passa alla successiva, fino a che ogni sequenza iterabile viene esaurita. Questo metodo viene utilizzaro per trattare sequenze consecutive come se fossero una singola sequenza. Equivalente a:

     def chain(*iterables):
         for it in iterables:
             for element in it:
                 yield element

count( [n])
Crea un iteratore che restituisce interi consecutivi a partire da n. Se non specificato il valore predefinito di n è zero. Attualmente gli interi long di Python non vengono supportati. Questo metodo viene spesso usato come argomento di imap() per generare punti di dati consecutivi. Utile anche con izip() per aggiungere sequenze di numeri. Equivalente a:

     def count(n=0):
         while True:
             yield n
             n += 1

Notate, count() non esegue controlli di overflow e restituisce numeri negativi dopo aver superato sys.maxint. Questo comportamento potrebbe cambiare in futuro.

cycle( iterable)
Crea un iteratore che restituisce elementi da iterable salvando una copia di ciascuno. Quando la sequenza viene terminata, restituisce gli elementi dalla copia salvata. Si ripete indefinitamente. Equivalente a:

     def cycle(iterable):
         saved = []
         for element in iterable:
             yield element
             saved.append(element)
         while saved:
             for element in saved:
                   yield element

Notate, questo è l'unico membro del toolkit che può richiedere un notevole spazio di memoria (in funzione della lunghezza della sequenza).

dropwhile( predicate, iterable)
Crea un iteratore che scorre gli elementi di iterable fin quando il predicato è vero; dopodichè restituisce ogni elemento. Notate, l'iteratore non produce alcun risultato finché il predicato è vero, perciò può avere un lungo tempo di avvio. Equivalente a:

     def dropwhile(predicate, iterable):
         iterable = iter(iterable)
         for x in iterable:
             if not predicate(x):
                 yield x
                 break
         for x in iterable:
             yield x

groupby( iterable[, key])
Crea un iteratore che restituisce chiavi e gruppi consecutivi da iterable. key è una funzione che calcola un valore chiave per ogni elemento. Se non viene specificata o è None, il valore predefinito di key è la funzione identica che restituisce l'elemento immutato. Generalmente, l'iterabile deve già essere ordinato con la stessa funzione chiave.

Il gruppo restituito è esso stesso un iteratore che condivide l'iterabile sottostante con groupby(). Poiché la sorgente è condivisa, quando l'oggetto groupby viene fatto avanzare, il gruppo precedente non è più visibile. Quindi, se i dati sono necessari in seguito, devono essere memorizzati in una lista:

    groups = []
    uniquekeys = []
    for k, g in groupby(data, keyfunc):
        groups.append(list(g))      # Salva l'iteratore di gruppo come lista.
        uniquekeys.append(k)

groupby() è equivalente a:

    class groupby(object):
        def __init__(self, iterable, key=None):
            if key is None:
                key = lambda x: x
            self.keyfunc = key
            self.it = iter(iterable)
            self.tgtkey = self.currkey = self.currvalue = xrange(0)
        def __iter__(self):
            return self
        def next(self):
            while self.currkey == self.tgtkey:
                self.currvalue = self.it.next() # Esce da StopIteration
                self.currkey = self.keyfunc(self.currvalue)
            self.tgtkey = self.currkey
            return (self.currkey, self._grouper(self.tgtkey))
        def _grouper(self, tgtkey):
            while self.currkey == tgtkey:
                yield self.currvalue
                self.currvalue = self.it.next() # Esce da StopIteration
                self.currkey = self.keyfunc(self.currvalue)
Nuovo nella versione 2.4.

ifilter( predicate, iterable)
Crea un iteratore che filtra gli elementi dall'iterabile iterable restituendo solo quelli per i quali predicate è True. Se il predicato, predicate, è None, restituisce gli elementi che sono veri. Equivalente a:

     def ifilter(predicate, iterable):
         if predicate is None:
             predicate = bool
         for x in iterable:
             if predicate(x):
                 yield x

ifilterfalse( predicate, iterable)
Crea un iteratore che filtra gli elementi dall'iterabile iterable restituendo solo quelli per i quali predicate è False. Se predicate è None, restituisce gli elementi che sono falsi. Equivalente a:

     def ifilterfalse(predicate, iterable):
         if predicate is None:
             predicate = bool
         for x in iterable:
             if not predicate(x):
                 yield x

imap( function, *iterables)
Crea un iteratore che calcola la funzione function usando argomenti da ognuno degli iterabili iterables. Se la funzione è posta a None, allora imap() restituisce gli argomenti come una tupla. È simile a map() ma si interrompe quando l'iterabile più breve si è esaurito, invece che riempire di None gli iterabili più corti. Il motivo della differenza è che argomenti di iteratori infiniti in genere mandano in errore map() (poiché l'output viene valutato completamente) ma rappresenta una via comune e comoda per fornire argomenti a imap(). Equivalente a:

     def imap(function, *iterables):
         iterables = map(iter, iterables)
         while True:
             args = [i.next() for i in iterables]
             if function is None:
                 yield tuple(args)
             else:
                 yield function(*args)

islice( iterable, [start,] stop [, step])
Crea un iteratore che restituisce gli elementi selezionati da iterable. Se start è diverso da zero, gli elementi di iterable vengono saltati fino a raggiungere l'indice start. In seguito, gli elementi vengono restituiti in successione a meno che step, che indica il numero di elementi da saltare ad ogni passaggio, non sia più grande di uno. Se stop è None, l'iterazione continua fino all'esaurimento dell'iteratore, altrimenti si ferma alla posizione specificata. Diversamente dall'affettamento regolare, islice() non supporta valori negativi per start, stop o step. Questo metodo può venire usato per estrarre campi specifici da dati che presentano una struttura interna appiattita (per esempio, un rapporto multi-linea può presentare un campo nome ogni tre linee). Equivalente a:

     def islice(iterable, *args):
         s = slice(*args)
         next, stop, step = s.start or 0, s.stop, s.step or 1
         for cnt, element in enumerate(iterable):
             if cnt < next:
                 continue
             if stop is not None and cnt >= stop:
                 break
             yield element
             next += step

izip( *iterables)
Crea un iteratore che aggrega elementi da ognuno degli iterabili iterables. Somiglia a zip() eccetto per il fatto che restituisce un iteratore invece di una lista. Questo metodo viene utilizzato per iterazioni lock-step su diversi iterabili contemporaneamente. Equivalente a:

     def izip(*iterables):
         iterables = map(iter, iterables)
         while iterables:
             result = [i.next() for i in iterables]
             yield tuple(result)

Modificato nella versione 2.4: Se non vengono specificati iterables, il metodo restituisce un iteratore di lunghezza zero invece di sollevare un'eccezione TypeError.

repeat( object[, times])
Crea un iteratore che restituisce l'oggetto object in continuazione. Viene eseguito indefinitamente a meno che non venga specificato l'argomento times. Questo metodo viene utilizzato come argomento di imap() per passare sempre gli stessi parametri alla funzione chiamata. Usato anche con izip() per creare una parte invariante di un record di tuple. Equivalente a:

     def repeat(object, times=None):
         if times is None:
             while True:
                 yield object
         else:
             for i in xrange(times):
                 yield object

starmap( function, iterable)
Crea un iteratore che calcola la funzione function usando tuple di argomenti ottenuti da iterable. Questo metodo viene usato al posto di imap() quando i parametri di argomento sono già stati raggruppati in tuple da un singolo iterabile (i dati sono stati ``pre-zippati''). La differenza tra imap() e starmap() equivale alla distinzione tra function(a,b) e function(*c). Equivalente a:

     def starmap(function, iterable):
         iterable = iter(iterable)
         while True:
             yield function(*iterable.next())

takewhile( predicate, iterable)
Crea un iteratore che restituisce gli elementi dell'iterabile iterable finché predicate è vero. Equivalente a:

     def takewhile(predicate, iterable):
         for x in iterable:
             if predicate(x):
                 yield x
             else:
                 break

tee( iterable[, n=2])
Restituisce n iteratori indipendenti da un singolo iterabile iterable. Nel caso in cui n sia due è equivalente a:

     def tee(iterable):
         def gen(next, data={}, cnt=[0]):
             for i in count():
                 if i == cnt[0]:
                     item = data[i] = next()
                     cnt[0] += 1
                 else:
                     item = data.pop(i)
                 yield item
         it = iter(iterable)
         return (gen(it.next), gen(it.next))

Notate, una volta che tee() ha fatto una suddivisione, l'iterabile iterable originale non dovrebbe essere più usato altrove; altrimenti iterable potrebbe venire fatto avanzare senza che gli oggetti di tee() ne siano informati.

Notate, questo membro del toolkit potrebbe richiedere un notevole spazio di memoria (a seconda della quantità di dati temporanei che è necessario immagazzinare). In genere, se un iteratore dovrà utilizzare tutti o gran parte i dati prima dell'altro iteratore, è più veloce l'utilizzo di list() piuttosto che di tee(). Nuovo nella versione 2.4.

Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.