Cosa sono esattamente iteratore, iterabile e iterazione?


444

Qual è la definizione di base di "iterabile", "iteratore" e "iterazione" in Python?

Ho letto più definizioni ma non riesco a identificare il significato esatto in quanto ancora non affonderà.

Qualcuno può aiutarmi con le 3 definizioni in termini laici?

Risposte:


531

Iterazione è un termine generale per prendere ogni elemento di qualcosa, uno dopo l'altro. Ogni volta che usi un ciclo, esplicito o implicito, per esaminare un gruppo di elementi, si tratta dell'iterazione.

In Python, iterabile e iteratore hanno significati specifici.

Un iterabile è un oggetto che ha un __iter__metodo che restituisce un iteratore o che definisce un __getitem__metodo che può prendere indici sequenziali a partire da zero (e genera un IndexErrorquando gli indici non sono più validi). Quindi un iterabile è un oggetto da cui puoi ottenere un iteratore .

Un iteratore è un oggetto con un metodo next(Python 2) o __next__(Python 3).

Ogni volta che usi un forciclo, o map, o una comprensione della lista, ecc. In Python, il nextmetodo viene chiamato automaticamente per ottenere ogni elemento dall'iteratore , quindi attraverso il processo di iterazione .

Un buon punto di partenza per l'apprendimento sarebbe la sezione iteratori del tutorial e la sezione tipi iteratori della pagina dei tipi standard . Dopo aver compreso le basi, provare la sezione iteratori del HOWTO sulla programmazione funzionale .


1
Si noti che collections.abc.AsyncIteratortest __aiter__e __anext__metodi. Questa è una nuova aggiunta in 3.6.
Janus Troelsen,

1
@jlh perché sarebbe __len__necessariamente legato all'iterazione? In che modo conoscere la lunghezza di qualcosa ti aiuterebbe a scorrere su di esso?
Shadowtalker,

2
@shadowtalker sarebbe utile sapere quali indici sono validi, quindi sai con quali indici è possibile utilizzare __getitem__.
jlh

4
@jlh sembra che tu stia proponendo un comportamento sfacciato molto supponente. Considera che {'a': 'hi', 'b': 'bye'}ha una lunghezza di 2, ma non può essere indicizzato da 0, 1 o 2.
shadowtalker

2
@shadowtalker. Ma un dict ha un __iter__metodo. Penso che jlh si riferisca ad oggetti iterabili specificamente perché definiscono: "un __getitem__metodo che può prendere indici sequenziali a partire da zero".
Ricco

337

Ecco la spiegazione che uso nell'insegnamento delle classi Python:

Un ITERABLE è:

  • qualsiasi cosa su cui è possibile eseguire il loop (ovvero è possibile eseguire il loop su una stringa o un file) o
  • tutto ciò che può apparire sul lato destro di un for-loop: for x in iterable: ...o
  • qualsiasi cosa tu possa chiamare con iter()ciò restituirà un ITERATOR: iter(obj)o
  • un oggetto che definisce __iter__ che restituisce un nuovo ITERATOR o potrebbe avere un __getitem__metodo adatto per la ricerca indicizzata.

Un ITERATOR è un oggetto:

  • con stato che ricorda dove si trova durante l'iterazione,
  • con un __next__ metodo che:
    • restituisce il valore successivo nell'iterazione
    • aggiorna lo stato in modo che punti al valore successivo
    • segnala quando è fatto sollevando StopIteration
  • e questo è auto-iterabile (nel senso che ha un __iter__metodo che ritorna self).

Appunti:

  • Il __next__metodo in Python 3 è scritto nextin Python 2 e
  • La funzione integrata next() chiama quel metodo sull'oggetto passato ad esso.

Per esempio:

>>> s = 'cat'      # s is an ITERABLE
                   # s is a str object that is immutable
                   # s has no state
                   # s has a __getitem__() method 

>>> t = iter(s)    # t is an ITERATOR
                   # t has state (it starts by pointing at the "c"
                   # t has a next() method and an __iter__() method

>>> next(t)        # the next() function returns the next value and advances the state
'c'
>>> next(t)        # the next() function returns the next value and advances
'a'
>>> next(t)        # the next() function returns the next value and advances
't'
>>> next(t)        # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration

>>> iter(t) is t   # the iterator is self-iterable

cosa intendi con iteratore fresco?
lmiguelvargasf,

13
@lmiguelvargasf "Fresco" come in "nuovo e non consumato" anziché "esaurito o parzialmente consumato". L'idea è che un nuovo iteratore inizia all'inizio, mentre un iteratore parzialmente utilizzato riprende da dove era stato interrotto.
Raymond Hettinger,

I tuoi proiettili 2 °, 3 ° e 4 ° indicano chiaramente cosa intendi, in termini di costrutti o built-in python specifici o chiamate di metodo. Ma il primo proiettile ("tutto ciò che può essere passato in loop") non ha quella chiarezza. Inoltre, il primo proiettile sembra avere una sovrapposizione con il secondo proiettile, poiché il secondo proiettile riguarda i forloop e il primo proiettile riguarda il "looping over". Potresti affrontarli?
Fountainhead,

2
Consideriamo la riformulazione di "qualsiasi cosa tu possa chiamare iter()" come "qualsiasi cosa tu possa passare iter()"
Fountainhead,

98

Le risposte di cui sopra sono fantastiche, ma come la maggior parte di ciò che ho visto, non sottolineare il abbastanza distinzione per le persone come me.

Inoltre, le persone tendono ad avere "troppo Pythonic" mettendo definizioni come "X è un oggetto che ha __foo__() metodo". Tali definizioni sono corrette: si basano sulla filosofia della tipizzazione delle anatre, ma l'attenzione sui metodi tende a mettersi in mezzo quando si cerca di comprendere il concetto nella sua semplicità.

Quindi aggiungo la mia versione.


In linguaggio naturale,

  • iterazione è il processo di prendere un elemento alla volta in una fila di elementi.

In Python,

  • iterable è un oggetto che è, beh, iterable, che in poche parole, significa che può essere usato in iterazione, ad esempio con un forloop. Come? Utilizzando iteratore . Spiegherò di seguito.

  • ... mentre iteratore è un oggetto che definisce come eseguire effettivamente l'iterazione, in particolare qual è l' elemento successivo . Ecco perché deve avere un next()metodo.

Gli stessi iteratori sono anch'essi iterabili, con la distinzione che il loro __iter__()metodo restituisce lo stesso oggetto ( self), indipendentemente dal fatto che i suoi elementi siano stati consumati o meno dalle chiamate precedenti next().


Quindi cosa pensa l'interprete Python quando vede for x in obj:un'istruzione?

Guarda, a for ciclo. Sembra un lavoro per un iteratore ... Prendiamone uno. ... C'è questo objragazzo, quindi chiediamolo.

"Mr. obj, hai il tuo iteratore?" (... chiama iter(obj), che chiama obj.__iter__(), che distribuisce felicemente un nuovo brillante iteratore_i .)

OK, è stato facile ... Cominciamo a iterare allora. ( x = _i.next()... x = _i.next()...)

Poiché Mr. è objriuscito in questo test (avendo un certo metodo che restituisce un iteratore valido), lo premiamo con l'aggettivo: ora puoi chiamarlo "Mr. iterabileobj ".

Tuttavia, in casi semplici, normalmente non beneficiate di avere iteratore e iterabile separatamente. Quindi definisci un solo oggetto, che è anche il suo iteratore. (A Python non importa davvero che _idistribuito da objnon sia poi così brillante, ma solo ilobj stesso.)

Questo è il motivo per cui nella maggior parte degli esempi che ho visto (e ciò che mi aveva confuso ancora e ancora), puoi vedere:

class IterableExample(object):

    def __iter__(self):
        return self

    def next(self):
        pass

invece di

class Iterator(object):
    def next(self):
        pass

class Iterable(object):
    def __iter__(self):
        return Iterator()

Ci sono casi, tuttavia, in cui è possibile trarre vantaggio dalla separazione dell'iteratore dall'iterabile, ad esempio quando si desidera avere una riga di elementi, ma più "cursori". Ad esempio, quando si desidera lavorare con elementi "correnti" e "imminenti", è possibile avere iteratori separati per entrambi. O più thread estratti da un enorme elenco: ognuno può avere il proprio iteratore per attraversare tutti gli elementi. Vedi @ Raymond's e @ glglgl's risposte di sopra.

Immagina cosa potresti fare:

class SmartIterableExample(object):

    def create_iterator(self):
        # An amazingly powerful yet simple way to create arbitrary
        # iterator, utilizing object state (or not, if you are fan
        # of functional), magic and nuclear waste--no kittens hurt.
        pass    # don't forget to add the next() method

    def __iter__(self):
        return self.create_iterator()

Appunti:

  • Lo ripeterò ancora: iteratore non è iterabile . Iteratore non può essere utilizzato come "sorgente" in forloop. Ciò di cui il forloop ha principalmente bisogno è __iter__() (che restituisce qualcosa con next()).

  • Naturalmente, fornon è l'unico ciclo di iterazione, quindi sopra vale anche per alcuni altri costrutti ( while...).

  • Iteratore next()può lanciare StopIteration per fermare l'iterazione. Non è necessario, tuttavia, può iterare per sempre o utilizzare altri mezzi.

  • Nel suddetto "processo di pensiero", _inon esiste davvero. Ho inventato quel nome.

  • C'è una piccola modifica in Python 3.x: next()ora è necessario chiamare il metodo (non il built-in) __next__(). Sì, avrebbe dovuto essere così da sempre.

  • Puoi anche pensarlo in questo modo: iterable ha i dati, iterator estrae l'elemento successivo

Disclaimer: non sono uno sviluppatore di alcun interprete Python, quindi non so davvero cosa "interpreti". Le riflessioni sopra sono solo una dimostrazione di come comprendo l'argomento da altre spiegazioni, esperimenti ed esperienze di vita reale di un novizio di Python.


1
È fantastico, ma sono ancora un po 'confuso. Pensavo che la tua scatola gialla dicesse che un forciclo ha bisogno di un iteratore ("Guarda, un ciclo for. Sembra un lavoro per un iteratore ... Prendiamone uno"). Ma poi dici nelle note alla fine che "Iteratore non può essere usato come sorgente in un forciclo" ...?
Racing Tadpole,

Perché inserisci solo passil codice per quelle nextdefinizioni? Suppongo che intendi solo che qualcuno deve implementare un modo per ottenere il prossimo, dal momento che il prossimo deve restituire qualcosa.
nealmcb,

@nealmcb Sì, penso che sia quello che significava passato me. (Questo è ciò che passserve , dopo tutto.)
Alois Mahdal

@AloisMahdal Ahh, non ne avevo mai visto prima. Quando vedo pass, penso che sia lì per motivi sintattici. Ho appena incontrato le risposte all'oggetto puntini di sospensione che sono piuttosto interessanti: puoi usare ...per indicare un blocco "todo later". NotImplementedè anche disponibile.
nealmcb,

Mentre mi piace che stai sottolineando la distinzione tra un iteratore e un iterabile, questa risposta si contraddice. Per prima cosa scrivi "Gli stessi iteratori sono anche iterabili" (che corrisponde a ciò che è scritto nella documentazione di Python ). Ma in seguito scrivi: ' iteratore non è iterabile . Iteratore non può essere utilizzato come "sorgente" in forloop '. Ottengo il punto della tua risposta, e mi piacerebbe altrimenti, ma penso che trarrebbe beneficio dal risolvere questo.
Ricco

22

Un iterabile è un oggetto che ha un __iter__()metodo. Può eventualmente essere ripetuto più volte, come ad esempio list()s e tuple()s.

Un iteratore è l'oggetto che itera. Viene restituito da un __iter__()metodo, si restituisce tramite il proprio __iter__()metodo e ha un next()metodo ( __next__()in 3.x).

L'iterazione è il processo per chiamare questo next()resp. __next__()fino a quando non si alza StopIteration.

Esempio:

>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1

Quindi davvero è solo un oggetto che passa attraverso il container? sarebbe stato utile?
thechrishaddad il

Spesso, ma non sempre. Un cursore generatore, file o database può essere iterato una sola volta e quindi sono i propri iteratori.
glglgl

Immagino che b2 non debba essere indipendente da b1? per questo caso speciale, è indipendente, certo che posso renderlo non indipendente ma anche valido Iterable.
Bin

@Bin Sì. Come ed Iteratorè sempre Iterableed è suo Iterator, due chiamate di iter()non danno necessariamente due Iterators indipendenti .
glglgl

13

Ecco il mio cheat sheet:

 sequence
  +
  |
  v
   def __getitem__(self, index: int):
  +    ...
  |    raise IndexError
  |
  |
  |              def __iter__(self):
  |             +     ...
  |             |     return <iterator>
  |             |
  |             |
  +--> or <-----+        def __next__(self):
       +        |       +    ...
       |        |       |    raise StopIteration
       v        |       |
    iterable    |       |
           +    |       |
           |    |       v
           |    +----> and +-------> iterator
           |                               ^
           v                               |
   iter(<iterable>) +----------------------+
                                           |
   def generator():                        |
  +    yield 1                             |
  |                 generator_expression +-+
  |                                        |
  +-> generator() +-> generator_iterator +-+

Quiz: vedi come ...

  1. ogni iteratore è un iterabile?
  2. il __iter__()metodo di un oggetto contenitore può essere implementato come generatore?
  3. un iterabile che ha un __next__metodo non è necessariamente un iteratore?

risposte:

  1. Ogni iteratore deve avere un __iter__metodo. Avere __iter__è abbastanza per essere un iterabile. Pertanto ogni iteratore è iterabile.
  2. Quando __iter__viene chiamato, dovrebbe restituire un iteratore ( return <iterator>nel diagramma sopra). Chiamare un generatore restituisce un iteratore generatore che è un tipo di iteratore.

    class Iterable1:
        def __iter__(self):
            # a method (which is a function defined inside a class body)
            # calling iter() converts iterable (tuple) to iterator
            return iter((1,2,3))
    
    class Iterable2:
        def __iter__(self):
            # a generator
            for i in (1, 2, 3):
                yield i
    
    class Iterable3:
        def __iter__(self):
            # with PEP 380 syntax
            yield from (1, 2, 3)
    
    # passes
    assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
  3. Ecco un esempio:

    class MyIterable:
    
        def __init__(self):
            self.n = 0
    
        def __getitem__(self, index: int):
            return (1, 2, 3)[index]
    
        def __next__(self):
            n = self.n = self.n + 1
            if n > 3:
                raise StopIteration
            return n
    
    # if you can iter it without raising a TypeError, then it's an iterable.
    iter(MyIterable())
    
    # but obviously `MyIterable()` is not an iterator since it does not have
    # an `__iter__` method.
    from collections.abc import Iterator
    assert isinstance(MyIterable(), Iterator)  # AssertionError

1
Nel quiz ho capito solo il primo punto. cioè iteratore diventa un iterabile in quanto ha __iter__metodo. Potete per favore approfondire il 2o e il 3o punto modificando questa risposta
AnV

@AnV: Per quanto ho capito: re 2 .: __iter__()restituisce un iteratore. Un generatore è un iteratore, quindi può essere utilizzato per questo scopo. Ri 3 .: Posso solo indovinare qui, ma penso che se __iter__()manca o non ritorna self, non è un iteratore, perché un iteratore __iter__()deve tornare self.
glglgl

10

Non so se aiuta qualcuno, ma mi piace sempre visualizzare i concetti nella mia testa per capirli meglio. Quindi, dato che ho un figlio piccolo, visualizzo il concetto iterabile / iteratore con mattoni e carta bianca.

Supponiamo di essere nella stanza buia e sul pavimento abbiamo mattoni per mio figlio. I mattoni di diverse dimensioni, colore, non importa adesso. Supponiamo di avere 5 mattoni come quelli. Quei 5 mattoni possono essere descritti come un oggetto - diciamo kit di mattoni . Possiamo fare molte cose con questo kit di mattoni: possiamo prenderne uno e poi prendere il secondo e poi il terzo, possiamo cambiare i luoghi dei mattoni, mettere il primo mattone sopra il secondo. Possiamo fare molte cose con quelle. Pertanto, questo kit di mattoni è un oggetto o una sequenza iterabile poiché possiamo attraversare ogni mattone e fare qualcosa con esso. Possiamo farlo solo come il mio piccolo figlio: possiamo giocare con un mattone alla volta . Quindi immagino di nuovo che questo kit di mattoni sia uniterabile .

Ora ricorda che siamo nella stanza buia. O quasi buio. Il fatto è che non vediamo chiaramente quei mattoni, di che colore sono, che forma ecc. Quindi anche se vogliamo fare qualcosa con loro - alias iterarli attraverso di loro - non sappiamo davvero cosa e come perché è troppo scuro.

Quello che possiamo fare è vicino al primo mattone - come elemento di un kit di mattoni - possiamo mettere un pezzo di carta fluorescente bianca in modo che possiamo vedere dove si trova il primo elemento in mattoni. E ogni volta che prendiamo un mattone da un kit, sostituiamo il pezzo di carta bianco a un mattone successivo per poterlo vedere nella stanza buia. Questo pezzo di carta bianco non è altro che un iteratore . È anche un oggetto . Ma un oggetto con ciò su cui possiamo lavorare e giocare con elementi del nostro oggetto iterabile - kit di mattoni.

Questo a proposito spiega il mio errore iniziale quando ho provato quanto segue in un IDLE e ho ricevuto un TypeError:

 >>> X = [1,2,3,4,5]
 >>> next(X)
 Traceback (most recent call last):
    File "<pyshell#19>", line 1, in <module>
      next(X)
 TypeError: 'list' object is not an iterator

La lista X qui era il nostro kit di mattoncini ma NON un pezzo di carta bianco. Prima dovevo trovare un iteratore:

>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>

Non so se aiuta, ma mi ha aiutato. Se qualcuno potesse confermare / correggere la visualizzazione del concetto, sarei grato. Mi aiuterebbe a saperne di più.


6

Iterabile : - qualcosa che è iterabile è iterabile; come sequenze come elenchi, stringhe ecc. Ha anche il __getitem__metodo o un __iter__metodo. Ora se usiamo la iter()funzione su quell'oggetto, avremo un iteratore.

Iteratore : - Quando otteniamo l'oggetto iteratore dalla iter()funzione; chiamiamo __next__()metodo (in python3) o semplicemente next()(in python2) per ottenere elementi uno per uno. Questa classe o istanza di questa classe è chiamata iteratore.

Da documenti: -

L'uso di iteratori pervade e unifica Python. Dietro le quinte, l'istruzione for chiama  iter() l'oggetto contenitore. La funzione restituisce un oggetto iteratore che definisce il metodo  __next__() che accede agli elementi nel contenitore uno alla volta. Quando non ci sono più elementi,  __next__() genera un'eccezione StopIteration che dice al ciclo for di terminare. È possibile chiamare il  __next__() metodo utilizzando la  next() funzione integrata; questo esempio mostra come funziona tutto:

>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    next(it)
StopIteration

Ex di una classe: -

class Reverse:
    """Iterator for looping over a sequence backwards."""
    def __init__(self, data):
        self.data = data
        self.index = len(data)
    def __iter__(self):
        return self
    def __next__(self):
        if self.index == 0:
            raise StopIteration
        self.index = self.index - 1
        return self.data[self.index]


>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
...     print(char)
...
m
a
p
s

4

Non penso che puoi ottenerlo molto più semplice della documentazione , tuttavia proverò:

  • Iterable è qualcosa che può essere ripetuto . In pratica di solito significa una sequenza, ad esempio qualcosa che ha un inizio e una fine e un modo per passare attraverso tutti gli elementi in essa contenuti.
  • Puoi pensare a Iterator come uno pseudo-metodo helper (o pseudo-attributo) che fornisce (o conserva) il prossimo (o primo) elemento nell'iterabile . (In pratica è solo un oggetto che definisce il metodo next())

  • L'iterazione è probabilmente meglio spiegata dalla definizione di Merriam-Webster della parola :

b: la ripetizione di una sequenza di istruzioni del computer per un determinato numero di volte o fino a quando una condizione è soddisfatta - confrontare la ricorsione


3
iterable = [1, 2] 

iterator = iter(iterable)

print(iterator.__next__())   

print(iterator.__next__())   

così,

  1. iterableè un oggetto su cui è possibile eseguire il loop . ad es. elenco, stringa, tupla ecc.

  2. l'utilizzo della iterfunzione sul nostro iterableoggetto restituirà un oggetto iteratore.

  3. ora questo oggetto iteratore ha un metodo chiamato __next__(in Python 3 o solo nextin Python 2) con il quale è possibile accedere a ciascun elemento di iterabile.

quindi, USCITA DEL CODICE SOPRA SARÀ:

1

2


3

Gli Iterabili hanno un __iter__metodo che crea un'istanza di un nuovo iteratore ogni volta.

Gli iteratori implementano un __next__metodo che restituisce singoli elementi e a__iter__ metodo che restituisce self.

Pertanto, gli iteratori sono anche iterabili, ma gli iterabili non sono iteratori.

Luciano Ramalho, Fluent Python.


2

Prima di occuparsi degli iterabili e degli iteratori, il fattore principale che decide l'iterabile e l'iteratore è la sequenza

Sequenza: la sequenza è la raccolta di dati

Iterable: Iterable è l'oggetto del tipo di sequenza che supporta __iter__ metodo.

Metodo Iter: il metodo Iter prende la sequenza come input e crea un oggetto che è noto come iteratore

Iteratore: gli Iteratore sono l'oggetto che chiama il metodo successivo e attraversa la sequenza. Chiamando il metodo successivo restituisce l'oggetto che ha attraversato attualmente.

esempio:

x=[1,2,3,4]

x è una sequenza che consiste nella raccolta di dati

y=iter(x)

Al momento della chiamata iter(x)restituisce un iteratore solo quando l'oggetto x ha un metodo iter, altrimenti genera un'eccezione. Se restituisce iteratore, allora y viene assegnato in questo modo:

y=[1,2,3,4]

Poiché y è un iteratore, quindi supporta next() metodo

Chiamando il metodo successivo restituisce i singoli elementi dell'elenco uno alla volta.

Dopo aver restituito l'ultimo elemento della sequenza, se chiamiamo di nuovo il metodo successivo, viene generato un errore StopIteration

esempio:

>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration

Solo un'osservazione: y = iter (x) non è esattamente y = [1,2,3,4] poiché y ora è un oggetto iteratore. Forse dovresti aggiungere un commento per chiarire che non è un elenco ma un oggetto iteratore o modificare la rappresentazione.
coelhudo,

-6

In Python tutto è un oggetto. Quando si dice che un oggetto è iterabile, significa che è possibile scorrere (cioè iterare) l'oggetto come una raccolta.

Le matrici per esempio sono iterabili. È possibile scorrere attraverso di essi con un ciclo for e passare dall'indice 0 all'indice n, n essendo la lunghezza dell'oggetto array meno 1.

Anche i dizionari (coppie di chiave / valore, chiamati anche array associativi) sono iterabili. Puoi scorrere le loro chiavi.

Ovviamente gli oggetti che non sono raccolte non sono iterabili. Un oggetto bool, ad esempio, ha solo un valore, Vero o Falso. Non è iterabile (non avrebbe senso che sia un oggetto iterabile).

Leggi di più. http://www.lepus.org.uk/ref/companion/Iterator.xml


6
gli oggetti che non sono raccolte non sono ripetibili non è generalmente vero. Per fare solo un paio di esempi, i generatori sono iterabili ma non sono raccolte e gli oggetti iteratore creati chiamando iter()i tipi di raccolta standard sono iterabili ma non sono essi stessi raccolte.
Mark Amery,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.