What is the best way to join tuples?

Terry Hancock hancock at anansispaceworks.com
Thu Nov 14 18:45:53 EST 2002


On Wednesday 13 November 2002 11:31 pm,  dique wrote:
> # I have two list of tuples, eg something like
> wxyTuple = [(1,1,1), (1,1,2), (1,2,1), (2,2,1)] # tuples of  (w,x,y)
> xyzTuple = [(1,1,0), (1,2,1), (1,1,2)] # tuples of (x,y,z)
> 
> # and I want to join them together become (w,x,y,z), just like what we used
> to do with RDBMS by joining two tables together, with x,y acting as pivot.
> The result should be:
> 
> wxyzTuple = [(1,1,1,0),(1,1,1,2),(1,1,2,1),(1,2,1,-1),(2,2,1,-1)] # where -1
> is to indicate no match is found in xyzTuple

Here's two ways --

Traditional loops (probably clearer, though perhaps ungainly):

>>> wxyTuple = [(1,1,1), (1,1,2), (1,2,1), (2,2,1)]
>>> xyzTuple = [(1,1,0), (1,2,1), (1,1,2)]
>>> wxyzTuple=[]
>>> for (w,x,y) in wxyTuple:
...     i=0
...     for (xp,yp,z) in xyzTuple:
...             if (x,y)==(xp,yp):
...                     wxyzTuple.append((w,x,y,z))
...                     i=1
...     if not i: wxyzTuple.append((w,x,y,-1))
... 
>>> wxyzTuple
[(1, 1, 1, 0), (1, 1, 1, 2), (1, 1, 2, 1), (1, 2, 1, -1), (2, 2, 1, -1)]

Using evil list comprehensions (well, I've seen worse, but these weren't that 
obvious). I find that the weird part is the outer-join business of 
substituting for missing matches. The easiest solution seems to be to do the 
two tasks separately:

>>> wxyzTuple = [(w,x,y,z) for (w,x,y) in wxyTuple
... 		for (xp,yp,z) in xyzTuple if (x,y)==(xp,yp)]

>>> wxyzTuple += [(w,x,y,-1) for (w,x,y) in wxyTuple 
... 		if (x,y) not in [(x,y) for (x,y,z) in xyzTuple]]
>>> wxyzTuple
[(1, 1, 1, 0), (1, 1, 1, 2), (1, 1, 2, 1), (1, 1, 1, -1), (2, 1, 1, -1)]

Cheers,
Terry

--
Terry Hancock ( hancock at anansispaceworks.com )
Anansi Spaceworks  http://www.anansispaceworks.com




More information about the Python-list mailing list