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