211 | | == countoccurrences() / countdistinct() == |
212 | | |
213 | | Written by Arnar Birgisson and shared on the IrcChannel. |
214 | | |
215 | | {{{ |
216 | | #!python |
217 | | def countoccurrences(numbers, minlength=0): |
218 | | """Takes a list of integers, in the range of 0..n and returns a list of integers |
219 | | where i-th item is the number of times i appears in the input list. |
220 | | |
221 | | If minlength is specified and n+1 < minlength, the returned list is |
222 | | right-padded with zeroes to make it contain minlength items. |
223 | | |
224 | | Examples: |
225 | | >>> countoccurrences([0,3,1,2,1,1,3,5]) |
226 | | [1,3,1,2,0,1] |
227 | | >>> countoccurrences([0,3,1,2,1,1,3,5], 10) |
228 | | [1,3,1,2,0,1,0,0,0,0] |
229 | | """ |
230 | | # TODO come up with a better name |
231 | | counts = [0] * max(max(numbers)+1, minlength) |
232 | | for x in numbers: |
233 | | counts[x] += 1 |
234 | | return counts |
235 | | }}} |
236 | | |
237 | | === Example usage === |
238 | | |
239 | | {{{ |
240 | | #!xml |
241 | | <py:with vars="counts = countoccurrences([p.status.value for p in subdir.job.pages], 3)"> |
242 | | <td><span style="color: #e18f01;">${counts[0]}</span></td> |
243 | | <td><span style="color: #249f0b;">${counts[1]}</span></td> |
244 | | <td><span style="color: #ae0a0a;">${counts[2]}</span></td> |
245 | | </py:with> |
246 | | }}} |
247 | | |
248 | | === Similar version with a dict, counts any hashable types === |
249 | | |
250 | | The previous function can only count occurrences of numbers. |
251 | | This counts occurrences of any hashable types and returns a dict instead of a list. |
252 | | {{{ |
253 | | #!python |
254 | | def countitemoccurrences(items, requireditems=[]): |
255 | | """Takes a list of hashable items and returns a dict whose keys are those |
256 | | items and the values are the counts of how many times each item appers in the list. |
257 | | |
258 | | If the list requireditems is specified it's values are guaranteed to be keys |
259 | | in the resulting dict, even if they don't appear in items in which case the count will be 0 |
260 | | |
261 | | Examples: |
262 | | >>> counttypes('blue green green'.split(), 'blue red green'.split()) |
263 | | {'blue': 1, 'green': 2, 'red': 0} |
264 | | """ |
265 | | counts = dict() |
266 | | for i in requireditems: |
267 | | counts[i] = 0 |
268 | | for i in items: |
269 | | counts[i] = counts.get(i, 0) + 1 |
270 | | return counts |
271 | | }}} |
272 | | |
273 | | === Generic version based on `itertools.groupby` === |
| 211 | === countoccurrences === |
| 212 | |
| 213 | Written by [http://www.cmlenz.net/ Christopher Lenz] with a small bugfix by Arnar. |
302 | | return dict([(g, 0) for g in groups] + |
303 | | [(g, len(list(l))) for g, l in groupby(iterable, key=key)]) |
| 242 | d = dict([(g, 0) for g in groups]) |
| 243 | for g, l in groupby(iterable, key=key): |
| 244 | d[g] = len(list(l)) + d.get(g, 0) |
| 245 | return d |