def memoize_generator(func):
 cache = Cache()
 def wrapped_func(*args, **kwargs):
  params = (args, tuple(sorted(kwargs.items())))
  try:
   cached = cache[params]
  except KeyError:
   cached = []
   for item in func(*args, **kwargs):
    cached.append(item)
    (yield item)
   cache[params] = cached
  else:
   for item in cached:
    (yield item)
 return wrapped_func

def memoize_generator ( func ) : cache = Cache ( ) def wrapped_func ( * args , ** kwargs ) : params = ( args , tuple ( sorted ( kwargs . items ( ) ) ) ) try : cached = cache [ params ] except KeyError : cached = [ ] for item in func ( * args , ** kwargs ) : cached . append ( item ) ( yield item ) cache [ params ] = cached else : for item in cached : ( yield item ) return wrapped_func
memoize decorator for generators store func results in a cache according to their arguments as memoize does but instead this works on decorators instead of regular functions .