Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
General hash_join function
def hash_join(left, right, join_key, attr_keys, outer=True):
"""
Allows you to join the keys/values from a list of dictionaries as the
attributes of a given list of objects.
Params::
- left - list of objects to join to
- right - list of dictionaries from which to get joined data
- join_key - attribute of both object and dictionary with which we can match
- attr_keys - the list of keys on the right dict you want to join
- outer - if a matching key is not found in right, outer = True would keep
the row in left and set all keys in attr_keys to None. outer = False would
delete the row in left if no matching join_key is found in right
"""
# convert list of dicts to a dict of dicts
# 2.7 only - right = {r.get(join_key): r for r in right}
right = dict((r.get(join_key), r) for r in right)
if not outer:
left[:] = filter(lambda x: right.get(getattr(x, join_key)), left)
# attach the inner dict values to the attr on the object
for l in left:
if not hasattr(l, join_key):
continue
else:
# check if the dict has a matching record
right_vals = right.get(getattr(l, join_key), {})
# attach attributes to objects
for key in attr_keys:
setattr(l, key, right_vals.get(key))
return left
class thingy(object):
pass
def build_things():
things = []
thing = thingy()
setattr(thing, 'group_id', 1)
things.append(thing)
thing2 = thingy()
setattr(thing2, 'group_id', 2)
things.append(thing2)
return things
stuff = [{'group_id': 1, 'group_name': 'Alex', 'group_size': 100}, {'group_name': 'Kevin', 'group_size': 200}]
whatsa = hash_join(build_things(), stuff, 'group_id', ['group_name', 'group_size'], outer=False)
for what in whatsa:
print getattr(what, 'group_id', None), getattr(what, 'group_name', None), getattr(what, 'group_size', None)
bobs = hash_join(build_things(), stuff, 'group_id', ['group_size'], outer=True)
for bob in bobs:
print getattr(bob, 'group_id', None), getattr(bob, 'group_name', None), getattr(bob, 'group_size', None)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment