I need a list with the following behavior
>>> 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
Although it can “emulated” via a dictionary, it’s not exactly the same. numpy array can behave this way, but I don’t want to import the whole numpy for something like this. Before coding it myself, I ask if something similar exists in the standard library.
Answers:
Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.
Method 1
Here’s minimal code to pass your given examples (with indispensable adjustments: you expect weird spacing and quoting, ‘None’ to be printed out at the prompt without a print statement, 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)
I imagine you’ll want more (to support negative indices, slicing, and whatever else), but this is all your examples are implicitly specifying.
Method 2
Dictionaries can be used as sparse lists.
Whilst they will not provide the characteristics you are after (as you are not actually after a sparse list, all the list elements are complete references to None in a dynamically-sized Array), they act as a textbook sparse array.
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'
Method 3
The sparse_list package provides the behaviour OP asks for.
All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0