Dovrei preferire i generatori Python agli elenchi?

8

Gli iteratori di Python possono essere molto efficienti in termini di memoria. Dovrei sempre preferire usare i generatori invece delle sole liste? In quali situazioni dovrei preferire un array semplice?

Ad esempio invece di questo:

emails = [user.email for user in users]

dovrei preferirlo?:

emails = (user.email for user in users)

Nota : intendo "generatori" e non "iteratori".

    
posta nicholaides 17.02.2015 - 22:18
fonte

2 risposte

7

Lo svantaggio principale dei generatori è che possono essere attraversati solo in una direzione. Non si può tornare a un valore precedente. Non puoi anche condividerli. Ci sono molti casi in cui ciò può essere facilmente tenuto in considerazione, o anche dove è preferibile, ma ci sono anche molti casi in cui non lo è. Ordinamento, per esempio.

Ecco perché un sacco di volte vedrai i generatori utilizzati per le fasi di elaborazione iniziali di una grande quantità di dati, quindi una volta filtrati in un sottoinsieme e mappati in un formato piacevole, vengono messi in un concreto duraturo struttura dei dati per un ulteriore utilizzo. In questo modo non spendi l'allocazione di memoria, i problemi di cache e i costi di raccolta dei rifiuti per gli array intermedi di grandi dimensioni che verranno immediatamente eliminati.

    
risposta data 17.02.2015 - 23:42
fonte
3

Hai iteratori confusi con i generatori.

Il tuo primo esempio è un elenco di espressioni iteratore mentre il secondo è un'espressione generatore. La differenza principale è che il generatore crea pigramente ogni membro della raccolta data (se necessario) piuttosto che ardentemente (immediatamente, se necessario o meno). Puoi definire i tuoi generatori utilizzando il rendimento anziché il rendimento.

Per quanto riguarda l'utilizzo, si desidera un iteratore quando è necessario l'elenco (o dizionario o altro) per qualcosa in sé e per sé. Dovresti usare un generatore quando la raccolta è accessoria al prodotto finale. Ad esempio, è possibile utilizzare un generatore per ottenere un elenco di numeri che soddisfano alcuni criteri da altri criteri. Non ti interessa la lista originale, solo i membri che soddisfano i criteri. Quindi, usi un generatore per ottenere solo quei numeri.

Un esempio più concreto sarebbe trovare gli angoli dei triangoli i cui lati hanno una determinata lunghezza. Non vogliamo tutti i triangoli falliti poveri e deformati, solo i triangoli di successo robusti e sani. Quindi useremmo un generatore.

Questo overflow dello stack post va più nel dettaglio.

    
risposta data 17.02.2015 - 22:36
fonte

Leggi altre domande sui tag