On Thu, Aug 13, 2009 at 11:16 PM, dou dou<nirvana...@gmail.com> wrote: > I have a function to do some thing like LEFT JOIN in SQL, the function use > the itemgetter to get the "ON" and "SELECT" parameters of the two table(list > of list), the problem is that itemgetter may return a value or a tuple of > values, because of the inconsistent return type of itemgetter, I have to do > 2^3 IF check, > the function like this: > > def left_join(table1, on_index1, table2, on_index2, getter1, getter2): > """do thing like: > SELECT on1(table1), g1(table1), g2(table2) FROM table1 > LEFT JOIN table2 > ON on1(table1) == on2(table2) > """ > on1 = itemgetter(*on_index1) > on2 = itemgetter(*on_index2) > g1 = itemgetter(*getter1) > g2 = itemgetter(*getter2) > > d2 = {} > d2 = dict((on2(r2), r2) for r2 in table2) > > #if itemgetter always return tuple, below could simple as one line > #return [ list(on1(r1) + g1(r1) + g2(d2.get(on1(r1)))) for r1 in table1 > ] > > len_on = len(on_index1) > len_g1 = len(getter1) > len_g2 = len(getter2) > > if len_on == 1: > if len_g1 == 1 and len_g2 == 1: > return [ [on1(r1), g1(r1), g2(d2.get(on1(r1)))] for r1 in table1 > ] > elif len_g1 == 1 and len_g2 > 1: > return [ list((on1(r1),g1(r1))+g2(d2.get(on1(r1)))) for r1 in > table1 ] > elif len_g1 > 1 and len_g2 == 1: > return [ list((on1(r1),)+g1(r1)+(g2(d2.get(on1(r1))),)) for r1 > in table1 ] > else: #len_g1 > 1 and len_g2 > 1: > return [ list((on1(r1),)+g1(r1)+g2(d2.get(on1(r1)))) for r1 in > table1 ] > else: # len_on > 1 > if len_g1 == 1 and len_g2 == 1: > return [ list(on1(r1))+[g1(r1),g2(d2.get(on1(r1)))] for r1 in > table1 ] > elif len_g1 == 1 and len_g2 > 1: > return [ list(on1(r1)+(g1(r1),)+g2(d2.get(on1(r1)))) for r1 in > table1 ] > elif len_g1 > 1 and len_g2 == 1: > return [ list(on1(r1)+g1(r1)+(g2(d2.get(on1(r1))),)) for r1 in > table1 ] > else: #len_g1 > 1 and len_g2 > 1: > return [ list(on1(r1)+g1(r1)+g2(d2.get(on1(r1)))) for r1 in > table1 ] > > so is there a way to force itemgetter to return tuple even when > itemgetter(only_have_one_argument)? or some other function to do this? > > Thanks. >
You can use a little helper function to create your itemgetter like this: def makeItemGetter(indexes): I = itemgetter(*indexes) if len(indexes) > 1: return I return lambda thing: (I(thing),) If indexes contains only one index the itemgetter is wrapped in a lambda that turns its output into a tuple. HTH, ~Simon -- http://mail.python.org/mailman/listinfo/python-list