3 # Author: Martin Matusiak <numerodix@gmail.com>
4 # Licensed under the GNU Public License, version 3.
10 def __init__(self
, init_list
=None, sort_key
=None):
12 self
.sort_key
= sort_key
15 for item
in init_list
:
18 def isvalid(self
, dict):
19 if type(dict) == sdict
:
23 return self
.lst
.__str
__()
34 def append(self
, dict):
35 if not self
.isvalid(dict):
36 raise Exception, "argument type of %s: %s invalid %s" %\
37 (dict, type(dict), sdict
)
39 self
= self
.sort(lst
=self
.lst
)
41 def remove(self
, index
):
42 try: del(self
.lst
[index
])
51 def get_top(self
, pred
=None):
52 if pred
: return filter(pred
, self
.lst
)[0]
55 def get_all(self
, pred
=None):
56 if pred
: return filter(pred
, self
.lst
)
59 def set_with(self
, keyname
, keyval
, f
):
60 f(filter(lambda dct
: dct
[keyname
] == keyval
, self
.lst
)[0])
62 def sort(self
, lst
=None, sort_key
=None, reverse
=False):
64 # insulate against unset keys
65 if sort_key
not in x
and sort_key
not in y
: return 0
66 elif sort_key
not in x
: return 1
67 if sort_key
not in y
: return -1
69 # numeric sort if string begins with digits
70 m
= regex
.find1("(-?[0-9]*)", x
[sort_key
])
71 n
= regex
.find1("(-?[0-9]*)", y
[sort_key
])
73 return cmp(int(n
), int(m
)) # reverse order to get desc
75 return cmp(x
[sort_key
].lower(), y
[sort_key
].lower())
77 if not lst
: lst
= self
.lst
78 if not sort_key
: sort_key
= self
.sort_key
79 lst
= sorted(lst
, compare
)
80 if reverse
: lst
.reverse()
83 l
.__dict
__['lst'] = lst
86 def ammend(self
, old
, new
): # update old dict with new data
87 if not new
: return old
88 for key
in new
.keys():
89 if not new
[key
] or new
[key
] == "":
91 for key
in [x
for x
in old
.keys() if x
not in new
.keys()]:
95 # merge new_dict into dictlist
96 def merge1(self
, new_dict
, key
):
99 for (i
, dict) in enumerate(dicts
):
100 if dict[key
] == new_dict
[key
]:
102 dicts
[i
] = self
.ammend(dict, new_dict
)
104 dicts
.append(new_dict
)
105 return self
.sort(lst
=dicts
)
107 # merge new dictlist into dictlist
108 def merge(self
, new_dicts
, key
):
110 if not new_dicts
: return dicts
111 for new_dict
in new_dicts
:
112 dicts
.merge1(new_dict
, key
)
113 return self
.sort(lst
=dicts
)
117 def __init__(self
, *args
):
120 if args
and len(args
) == 1:
122 for (key
, value
) in init_dict
.items():
123 self
.__setattr
__(key
, value
)
128 def ___value_is_null___(self
, value
):
130 # ignore null values and strings with only whitespace
131 if not value
or (type(value
) == str and value
.strip() == ""):
135 # Dictionary interface
137 def __setitem__(self
, key
, value
):
138 self
.__setattr
__(key
, value
)
140 def __getitem__(self
, key
):
141 return self
.__getattribute
__(key
)
143 def __delitem__(self
, key
):
144 self
.__delattr
__(key
)
147 for key
in dict.keys(self
):
148 self
.__delitem
__(key
)
150 def fromkeys(self
, keys
, value
=None):
153 for key
in keys
: new_sdict
.__setitem
__(key
, value
)
156 def pop(self
, key
, default
=None):
157 value
= self
.__getitem
__(key
)
158 self
.__delitem
__(key
)
159 if not value
: return default
165 return (key
, self
.pop(key
))
166 except IndexError: return None
168 def setdefault(self
, key
, value
=None):
169 v
= self
.__getitem
__(key
)
171 self
.__setitem
__(key
, value
)
174 def update(self
, pairs
):
175 for (key
, value
) in pairs
:
176 self
.__setattr
__(key
, value
)
179 # Attribute interface
181 def __setattr__(self
, key
, value
):
182 if not self
.___value
_is
_null
___(value
):
183 if type(value
) == int: value
= str(value
)
184 dict.__setattr
__(self
, key
, value
)
185 dict.__setitem
__(self
, key
, value
)
187 def __getattribute__(self
, key
):
189 return dict.__getattribute
__(self
, key
)
190 except AttributeError: return None
192 def __delattr__(self
, key
):
194 dict.__delattr
__(self
, key
)
195 dict.__delitem
__(self
, key
)
200 if __name__
== "__main__":
203 print "d['a']:", d
['a']
229 dl
= sdictlist(sort_key
="a")
236 print dl
.get_top(pred
=lambda x
: x
.a
!= None)
238 dl2
= sdictlist(sort_key
="c")
241 print dl
.merge(dl2
, "c")