2012-05-23 21 views
13

documentation kartezyen çarpım fonksiyonuPython'un itertools ürün bellek tüketimi

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

Bu nasıl jeneratörler ile mümkün olabileceğini söylüyor? Birisi bana 2 jeneratörü için sınırlı bir hafıza tüketimi olan bir örnek gösterebilir mi?

+3

Olası yinelenen [Neden itertools.product ile bir MemoryError alıyorum?] (Http://stackoverflow.com/q/8695422/222914) –

cevap

9

modülün kaynak kodunun baktığımızda, itertools.product() aslında bir tuplea Her tartışmayı dönüştürür: Başka bir deyişle

// 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; 
} 

, itertools.product() 'ın bellek tüketimi giriş argümanları boyutunda doğrusal olarak görünmektedir.

4

Eh, o da diyor ki: her değişiklikte ilerleyen sağdaki eleman bir kilometre sayacı gibi

iç içe döngüler döngüsü. Bu kalıp, bir lexicographic siparişi oluşturur; böylece, girdinin yineleyicileri sıralanırsa, ürün tuplleri sıralı bir şekilde yayınlanır.

Bu hemen hemen o uygulanmasında işleyiş şekli (Modules/itertoolsmodule.c)

İşte

devlet nesnesidir:

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; 

Ve ertesi öğe bu kullanır fonksiyonu product_next tarafından döndürülen durum ve sonraki durumu oluşturmak için alıntıda açıklanan algoritma. Bellek gereksinimlerini anlamak için this answer'a bakın.

Genel eğitim için, C uzantıları here'dan itibaren devletli jeneratörler oluşturma hakkında bilgi edinebilirsiniz.