|
1 | | -#!/usr/bin/env python |
2 | 1 |
|
| 2 | +""" |
| 3 | +example of emulating a sequence |
| 4 | +""" |
3 | 5 |
|
4 | 6 | class SparseArray(object): |
5 | | - def __init__(self, iterable): |
6 | | - self.values = {} |
7 | | - self.length = len(iterable) |
8 | | - for i, val in enumerate(iterable): |
9 | | - if val: |
10 | | - self.values[i] = val |
11 | | - print self.values |
12 | | - |
13 | | - def __getitem__(self, index): |
14 | | - if index >= self.length: |
15 | | - raise IndexError("sparse array index out of range") |
16 | | - else: |
17 | | - return self.values.get(index, 0) |
18 | 7 |
|
19 | | - def __setitem__(self, index, value): |
20 | | - if index >= self.length: |
21 | | - raise IndexError("sparse array index out of range") |
22 | | - else: |
23 | | - if value == 0: |
24 | | - self.values.pop(index, None) |
25 | | - else: |
26 | | - self.values[index] = value |
27 | | - |
28 | | - def __delitem__(self, index): |
29 | | - if index >= self.length: |
30 | | - raise IndexError("sparse array index out of range") |
31 | | - else: |
32 | | - self.values.pop(index, None) |
33 | | - self.length -= 1 |
| 8 | + def __init__(self, my_array=()): |
| 9 | + self.length = len(my_array) |
| 10 | + self.sparse_array = self.convert_to_sparse(my_array) |
34 | 11 |
|
| 12 | + def convert_to_sparse(self, my_array): |
| 13 | + sparse_array = {} |
| 14 | + for index, number in enumerate(my_array): |
| 15 | + if number: |
| 16 | + sparse_array[index] = number |
| 17 | + return sparse_array |
35 | 18 |
|
36 | 19 | def __len__(self): |
37 | 20 | return self.length |
| 21 | + |
| 22 | + def __getitem__(self, key): |
| 23 | + try: |
| 24 | + return self.sparse_array[key] |
| 25 | + except KeyError: |
| 26 | + if key >= self.length: |
| 27 | + raise IndexError('array index out of range') |
| 28 | + return 0 |
| 29 | + |
| 30 | + def __setitem__(self, key, value): |
| 31 | + if key > self.length: |
| 32 | + raise IndexError('array assignment index out of range') |
| 33 | + if value != 0: |
| 34 | + self.sparse_array[key] = value |
| 35 | + else: |
| 36 | + # if the value is being set to zero, we probably need to |
| 37 | + # remove a key from our dictionary. |
| 38 | + self.sparse_array.pop(key, None) |
| 39 | + |
| 40 | + def __delitem__(self, key): |
| 41 | + # we probably need to move the keys if we are not deleting the last |
| 42 | + # number, use pop in case it was a zero |
| 43 | + if key == self.length - 1: |
| 44 | + self.sparse_array.pop(key, None) |
| 45 | + else: |
| 46 | + # since we need to adjust all of the keys after the one we are |
| 47 | + # deleting, probably most efficient to create a new dictionary |
| 48 | + new_dict = {} |
| 49 | + for k, v in self.sparse_array.iteritems(): |
| 50 | + if k >= key: |
| 51 | + new_dict[k - 1] = v |
| 52 | + else: |
| 53 | + new_dict[k] = v |
| 54 | + # note we don't want to do update, since we need to make sure we are |
| 55 | + # getting rid of the old keys, when we moved the value to a new key |
| 56 | + self.sparse_array = new_dict |
| 57 | + # length is now one shorter |
| 58 | + self.length -= 1 |
| 59 | + |
| 60 | + |
| 61 | + |
| 62 | + |
0 commit comments