Python

2012-05-23 3 views
13

Il documentation dice che la funzione del prodotto cartesianoPython

the actual implementation does not build up intermediate results in memory. 

Come può essere possibile con i generatori? Qualcuno può mostrarmi un esempio con un consumo di memoria limitato per 2 generatori?

+3

Possibile duplicato di [Perché viene visualizzato un errore MemoryError con itertools.product?] (Http://stackoverflow.com/q/8695422/222914) –

risposta

9

Guardando il codice sorgente del modulo, itertools.product() effettivamente converte ogni argomento per una tupla:

// product_new() in itertoolsmodule.c 
for (i=0; i < nargs ; ++i) { 
    PyObject *item = PyTuple_GET_ITEM(args, i); 
    PyObject *pool = PySequence_Tuple(item); //<==== Call tuple(arg) 
    if (pool == NULL) 
     goto error; 
    PyTuple_SET_ITEM(pools, i, pool); 
    indices[i] = 0; 
} 

In altre parole, il consumo di memoria itertools.product() s' sembra essere lineare alla dimensione degli argomenti di input.

4

Beh, si dice anche:

Il nidificato ciclo di loop come un contachilometri con l'elemento più a destra avanzando su ogni iterazione. Questo modello crea un ordinamento lessicografico in modo tale che se i file iterati dell'input vengono ordinati, le tuple del prodotto vengono emesse in ordine.

Questo è più o meno come funziona nella realizzazione (Modules/itertoolsmodule.c)

Ecco l'oggetto Stato:

typedef struct { 
    PyObject_HEAD 
    PyObject *pools;  /* tuple of pool tuples */ 
    Py_ssize_t *indices; /* one index per pool */ 
    PyObject *result;  /* most recently returned result tuple */ 
    int stopped;   /* set to 1 when the product iterator is exhausted */ 
} productobject; 

E il prossimo articolo è restituito dalla funzione product_next, che utilizza questo stato e l'algoritmo descritto nella citazione per generare lo stato successivo. Vedere this answer per comprendere i requisiti di memoria.

Per l'istruzione generale, è possibile leggere come creare generatori con stato dalle estensioni C here.