Join python iterators on key -


i'm looking way join python iterators itertools.izip_longest() does, join elements have same "key" (as defined parameter) , output none when key not exist on iterators. i'm assuming iterators sorted ascending "key".

example:

iter1 = iter((1, 3, 4, 9)) iter2 = iter((3, 5, 6)) iter3 = iter((1, 3, 10))  zipjoiner(iter1, iter2, iter3) 

should give:

iter(((1, none, 1), (3, 3, 3), (4, none, none), (none, 5, none), (none, 6, none), (9, none, none), (none, none, 10))) 

(in case key default identity lambda x: x)

i've tried modify izip_longest() implementation found in python documentation , works (at least on example), i'm looking more elegant solution. idea?

this code:

def zipjoiner(*args, **kwds):     # izip_longest('abcd', 'xy', fillvalue='-') --> ax c- d-     fillvalue = kwds.get('fillvalue')     key = kwds.get('key', lambda x: x)     counter = [len(args) - 1]     def sentinel():         if not counter[0]:             raise zipexhausted         counter[0] -= 1         yield fillvalue     fillers = itertools.repeat(fillvalue)     iterators = [itertools.chain(it, sentinel(), fillers) in args]      def getkey(x):         return none if x none else key(x)      try:         while iterators:             elements = tuple(map(next, iterators))             keys = tuple(map(getkey, elements))             minkey = min(_ _ in keys if not _ none)             while not all(k == minkey k in keys):                 yield tuple(map(lambda (k, v): v if k == minkey else none, zip(keys, elements)))                 elements = tuple(map(lambda (k, it, v): it.next() if k == minkey else v, zip(keys, iterators, elements)))                 keys = tuple(map(getkey, elements))                 minkey = min(_ _ in keys if not _ none)             yield elements      except zipexhausted:         pass 

in case don't want preserve order turn lists sets, loop through sorted list of values input iterators , yield tuple values or none depending on whether value in corresponding set:

def join_iterators(*iterators):     sets = []     iterator in iterators:         sets.append(set(iterator))      values = set(itertools.chain(*iterators))     get_value_or_none = lambda value, s: value if value in s else none     value in sorted(values):         yield tuple(get_value_or_none(value, s) s in sets) 

this not address key function think figure out how apply ;)


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -