2009-12-07 16 views
10

Ho bisogno di una lista con il seguente comportamentolista attribuzioni sparse in python

>>> l = SparseList() 
>>> l 
[] 
>>> l[2] = "hello" 
>>> l 
[ None, None, "hello"] 
>>> l[5] 
None 
>>> l[4] = 22 
>>> l 
[ None, None, "hello", None, 22] 
>>> len(l) 
5 
>>> for i in l: print i 
None 
None 
"hello" 
None 
22 

Anche se può "emulata" tramite un dizionario, non è esattamente la stessa. array numpy può comportarsi in questo modo, ma non voglio importare l'intero numpy per qualcosa di simile. Prima di codificarlo da solo, chiedo se esiste qualcosa di simile nella libreria standard.

risposta

19

Ecco il codice minimo per passare i vostri esempi forniti (con aggiustamenti indispensabili: vi aspettate strano la spaziatura e citando, 'None' per essere stampato al prompt senza una dichiarazione print, etc etc):

class SparseList(list): 
    def __setitem__(self, index, value): 
    missing = index - len(self) + 1 
    if missing > 0: 
     self.extend([None] * missing) 
    list.__setitem__(self, index, value) 
    def __getitem__(self, index): 
    try: return list.__getitem__(self, index) 
    except IndexError: return None 

__test__ = dict(allem=''' 
>>> l = SparseList() 
>>> l 
[] 
>>> l[2] = "hello" 
>>> l 
[None, None, 'hello'] 
>>> print l[5] 
None 
>>> l[4] = 22 
>>> l 
[None, None, 'hello', None, 22] 
>>> len(l) 
5 
>>> for i in l: print i 
None 
None 
hello 
None 
22 
''') 
import doctest 
doctest.testmod(verbose=1) 

Immagino che ne vorrete di più (per supportare indici negativi, affettazioni e quant'altro), ma questo è tutto ciò che i vostri esempi stanno specificando implicitamente.

+0

Sono senza parole. Non mi aspettavo il codice :) Grazie :) –

+0

Tuttavia, ciò significa che non esiste nella libreria standard ... Posso includere il codice nella libreria wavemol (BSD)? –

+0

@Stefano, certo, consulta http://meta.stackexchange.com/questions/13976/who-owns-the-copyright-to-sofu-content: "contenuto fornito dall'utente con licenza cc-wiki con attribuzione richiesta" per Jeff La risposta di Attwood (credo che la licenza BSD sia compatibile con quella, ma sarò felice di fornirla a te altrimenti se necessario! -). –

2

I dizionari possono essere utilizzati come elenchi sparsi. Sebbene non forniscano le caratteristiche che si cercano (poiché in realtà non si trova dopo un elenco sparse, tutti gli elementi dell'elenco sono riferimenti completi a None in una matrice di dimensioni dinamiche), fungono da array sparse da manuale.

sparse_vars = [(0,"Hi"),(10000,"Bye"),(20000,"Try")] 
sparse_list = {} 

for var in sparse_vars: 
    sparse_list[var[0]] = var[1] 

>>> print sparse_list 
{0: 'Hi', 10000: 'Bye', 20000: 'Try'} 
>>> print sparse_list[20000] 
'Try'