2009-12-07 4 views
10

je besoin d'une liste avec le comportement suivantliste d'affectation clairsemée en 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 

Bien qu'il puisse « émulé » via un dictionnaire, ce n'est pas exactement la même chose. Le tableau numpy peut se comporter de cette façon, mais je ne veux pas importer tout le numpy pour quelque chose comme ça. Avant de le coder moi-même, je demande s'il existe quelque chose de similaire dans la bibliothèque standard.

Répondre

19

est ici un minimum de code pour passer vos exemples donnés (avec des ajustements indispensables: vous attendez un espacement étrange et citant, « None » à imprimer à l'invite sans une déclaration 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) 

J'imagine que vous en voudrez plus (pour prendre en charge les indices négatifs, le découpage en tranches et tout le reste), mais c'est tous vos exemples qui sont implicitement spécifiés.

+0

Je suis sans voix. Je ne m'attendais pas au code :) Merci :) –

+0

Cependant, cela signifie qu'il n'existe pas dans la bibliothèque standard ... puis-je inclure votre code dans la bibliothèque wavemol (BSD)? –

+0

@Stefano, bien sûr, voir http://meta.stackexchange.com/questions/13976/who-owns-the-copyright-to-sofu-content: "utilisateur a contribué au contenu sous licence cc-wiki avec attribution nécessaire" par Jeff La réponse d'Attwood (je crois que la licence BSD est compatible avec cela, mais je serai ravi de vous la relicquer autrement si nécessaire!). –

2

Les dictionnaires peuvent être utilisés comme des listes éparses. Alors qu'ils ne fourniront pas les caractéristiques que vous recherchez (comme vous n'êtes pas réellement après une liste éparse, tous les éléments de la liste sont des références complètes à None dans un tableau de taille dynamique), ils agissent comme un tableau sparse.

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'