Created
May 20, 2013 08:54
-
-
Save jnothman/5611142 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from collections import defaultdict | |
from six import iteritems | |
def group_params(items, key_name=lambda x: True): | |
"""bin by sub-dicts where values are compared by id if not hashable | |
>>> a = ('boo', 6) | |
>>> b = ('boo', 6) | |
>>> id(a) == id(b) | |
False | |
>>> import numpy | |
>>> c = numpy.array([1, 2, 3]) | |
>>> items = [{'p': a, 'q': 1}, {'p': b, 'q': 2}, {'p': c, 'q': 3}, {'p': c, 'q': 4}] | |
>>> groups = list(group_params(items, lambda x: x == "p")) | |
>>> len(groups) | |
2 | |
>>> groups | |
>>> sorted([[x['q'] for x in gitems] for g, gitems in groups if g['p'] == a][0]) | |
[1, 2] | |
>>> sorted([[x['q'] for x in gitems] for g, gitems in groups if g['p'] is c][0]) | |
[3, 4] | |
""" | |
# can reduce work if input is sorted tuples rather than dict | |
groups = defaultdict(list) | |
canonical = {} # maps hashable x to a canonical instance of x | |
id_to_obj = {} | |
for params in items: | |
group = [] | |
for k, v in iteritems(params): | |
if key_name(k): | |
try: | |
v_id = id(canonical.setdefault(v, v)) | |
except TypeError: | |
v_id = id(v) | |
id_to_obj[v_id] = v | |
group.append((k, v_id)) | |
groups[tuple(sorted(group))].append(params) | |
return [({k: id_to_obj[v_id] for k, v_id in group}, group_items) | |
for group, group_items in iteritems(groups)] | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment