
In Python, le funzioni itertools.count(), itertools.cycle() e itertools.repeat() nel modulo itertools della libreria standard possono essere utilizzate per creare iteratori infiniti.
In questo articolo vengono descritti i seguenti contenuti.
- Conta all’infinito:
itertools.count()
- Ciclo elementi di un iterabile indefinitamente:
itertools.cycle()
- Ripetere lo stesso valore all’infinito:
itertools.repeat()
Per ogni funzione vengono presentati esempi di processo iterativo con l’istruzione per e una combinazione con la funzione zip().
Vedere gli articoli seguenti per ulteriori informazioni sull’istruzione per e sulla funzione zip().
Se li usi nell’istruzione per, fai attenzione a specificare la condizione finale e l’interruzione; in caso contrario, il codice finirà in un ciclo infinito.
Cicli infiniti con contatori, ecc. possono essere implementati con l’istruzione mentre, ma spesso è più facile scriverli usando le funzioni itertools.
itertools.count() crea un iteratore che produce valori che conta avanti o indietro all’infinito.
Per configurazione predefinita, inizia da 0 e aumenta di 1.
import itertools
for i in itertools.count():
print(i)
if i > 3:
break
# 0
# 1
# 2
# 3
# 4
È possibile specificare il valore iniziale con il primo argomento start e l’incremento con il secondo argomento step.
for i in itertools.count(2):
print(i)
if i > 3:
break
# 2
# 3
# 4
for i in itertools.count(step=3):
print(i)
if i > 8:
break
# 0
# 3
# 6
# 9
for i in itertools.count(2, 3):
print(i)
if i > 8:
break
# 2
# 5
# 8
# 11
Se si desidera eseguire il conto alla rovescia, è possibile specificare un valore negativo per il passaggio.
for i in itertools.count(10, -1):
print(i)
if i < 8:
break
# 10
# 9
# 8
# 7
È possibile specificarlo come numero a virgola mobile float, ma in alcuni casi potrebbe essere più accurato utilizzare la moltiplicazione.
Quando si conta con numeri in virgola mobile, a volte è possibile ottenere una migliore precisione sostituendo il codice moltiplicativo come:
(start + step * i for i in count()).
itertools.count() — Functions creating iterators for efficient looping — Python 3.9.7 documentation
for i in itertools.count(0.1, 1.5):
print(i)
if i > 3:
break
# 0.1
# 1.6
# 3.1
for i in itertools.count():
ii = 0.1 + 1.5 * i
print(ii)
if ii > 3:
break
# 0.1
# 1.6
# 3.1
Se combinato con zip(), è possibile creare tuple con contatore.
l1 = ['a', 'b', 'c']
l2 = ['x', 'y', 'z']
print(list(zip(itertools.count(), l1, l2)))
# [(0, 'a', 'x'), (1, 'b', 'y'), (2, 'c', 'z')]
Nota che se usi enumerate() e zip(), vengono create tuple nidificate.
print(list(enumerate(zip(l1, l2))))
# [(0, ('a', 'x')), (1, ('b', 'y')), (2, ('c', 'z'))]
Se lo usi nel ciclo per, puoi anche usare enumerate() e zip() per estrarre ogni valore come segue.
names = ['Alice', 'Bob', 'Charlie']
ages = [24, 50, 18]
for i, (name, age) in enumerate(zip(names, ages)):
print(i, name, age)
# 0 Alice 24
# 1 Bob 50
# 2 Charlie 18
itertools.cycle() crea un iteratore che scorre all’infinito gli elementi di un oggetto iterabile come un elenco.
l = [1, 10, 100]
sum_value = 0
for i in itertools.cycle(l):
print(i)
sum_value += i
if sum_value > 300:
break
# 1
# 10
# 100
# 1
# 10
# 100
# 1
# 10
# 100
Esempio di specifica di range():
sum_value = 0
for i in itertools.cycle(range(3)):
print(i)
sum_value += i
if sum_value > 5:
break
# 0
# 1
# 2
# 0
# 1
# 2
Esempio di combinazione con zip():
l1 = [1, 10, 100]
l2 = [0, 1, 2, 3, 4, 5, 6]
print(list(zip(itertools.cycle(l1), l2)))
# [(1, 0), (10, 1), (100, 2), (1, 3), (10, 4), (100, 5), (1, 6)]
itertools.cycle() salva una copia dell’oggetto iterabile originale. Si noti che se la dimensione dell’oggetto iterabile è grande, potrebbe utilizzare memoria.
Nota, questo membro del toolkit potrebbe richiedere una notevole memoria ausiliaria (a seconda della lunghezza dell’iterabile).
itertools.cycle() — Funzioni che creano iteratori per cicli efficienti — Documentazione Python 3.9.7
itertools.repeat() crea un iteratore che restituisce lo stesso valore all’infinito.
sum_value = 0
for i in itertools.repeat(10):
print(i)
sum_value += i
if sum_value > 40:
break
# 10
# 10
# 10
# 10
# 10
Il numero di iterazioni può essere specificato con il secondo argomento volte.
for i in itertools.repeat(10, 3):
print(i)
# 10
# 10
# 10
Il primo argomento può essere qualsiasi oggetto. È anche possibile ripetere un oggetto funzione. Nell’esempio seguente viene ripetuta la funzione incorporata len().
for l in itertools.repeat([0, 1, 2], 3):
print(l)
# [0, 1, 2]
# [0, 1, 2]
# [0, 1, 2]
for func in itertools.repeat(len, 3):
print(func('abc'))
# 3
# 3
# 3
Esempio di combinazione con zip() è il seguente. Puoi aggiungere elementi costanti.
l = [0, 1, 2, 3]
print(list(zip(itertools.repeat(10), l)))
# [(10, 0), (10, 1), (10, 2), (10, 3)]