def lazy_lookup_tuple(iterable, *args, **kwargs): """ Generates a lookup over all iterations of the iterable. The keyword parameters are: - key: A function which, given an item in the iterable, returns the key upon which to lookup from the lookup objects. Defaults to the identity function. - default: The value which a field defaults to if nothing the item doesn't coorespond in the lookup. Defaults to None. All position arguments (excepting the first one) are objects that support lookup via __getitem__ (e.g. a dict object). This returns a generator which yields tuples of the form: (item, args[0][key(item)], args[1][key(item)], ...) """ default = None key_func = lambda x: x if 'key' in kwargs: key_func = kwargs['key'] if 'default' in kwargs: default = kwargs['default'] def get_item(object, key): try: return object[key] except KeyError: if callable(default): return default(key) else: return default for item in iterable: key = key_func(item) yield tuple([item] + map(lambda arg: get_item(arg, key), args)) def lazy_lookup_dict(iterable, *args, **kwargs): """ Generates a lookup over all iterations of the iterable. The keyword parameters are: - key: A function which, given an item in the iterable, returns the key upon which to lookup from the lookup objects. Defaults to the identity function. - default: The value which a field defaults to if nothing the item doesn't coorespond in the lookup. Defaults to None. - item_name: The label for the item in the dictionary that's yielded. Defaults to 'item'. All keyword arguments (except the above ones) are objects that support lookup via __getitem__ (e.g. a dict object). This returns a generator which yields dictionaries of the form: {'item': item, kwarg_name1: kwarg_value1[key(item)], ...} """ default = None key_func = lambda x: x item_name = 'item' if 'key' in kwargs: key_func = kwargs['key'] del kwargs['key'] if 'default' in kwargs: default = kwargs['default'] del kwargs['default'] if 'item_name' in kwargs: item_name = kwargs['item_name'] del kwargs['item_name'] def get_item(object, key): try: return object[key] except KeyError: if callable(default): return default(key) else: return default for item in iterable: key = key_func(item) yield dict([(item_name, item)] + map(lambda kwarg: (kwarg[0], get_item(kwarg[1], key)), kwargs.items()))