problem with interface of operator.itemgetter
Simon Forman
sajmikins at gmail.com
Sun Aug 16 14:33:30 EDT 2009
On Thu, Aug 13, 2009 at 11:16 PM, dou dou<nirvana117 at 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
More information about the Python-list
mailing list