[Tutor] list comprehension question

Blake Winton bwinton at latte.ca
Tue Jun 1 20:58:22 EDT 2004


On Tue, Jun 01, 2004 at 10:43:45PM +0000, Tom Musgrove wrote:
> >Was that a typo?
> Hi Blake, it was indeed a typo, new to the whole python thing...

No worries, just checking.

> Here is the solution I came up with
> >>>ListAUniqueEdges = [(1,5), (2,6), (3,7), (8,9)]
> >>>ListBUniqueEdges = [(2,7), (3,5), (1,6), (10,11)]
> >>>NewDict = {}
> >>>for k,v in ListAUniqueEdges:
> >>>    listTemp = []
> >>>    for m,n in ListBUniqueEdges:
> >>>        if((k==m)or(k==n)or(v==m)or(v==n)):
> >>>            if (listTemp == []) :
> >>>                listTemp = [(m,n)]
> >>>            else:
> >>>                listTemp.extend([(m,n)])
> >>>    NewDict[(k,v)] = listTemp
> >>>
> >>>NewDict
> {(3,7): [(2,7), (3,5)], (2,6): [(2,7), (1,6)], (8,9): [], (1,5):[(3,5), 
> (1,6)]}
> >>>
> So, it seems to work ok
> 
> I'd be interested if there is a 'better' or more elegant way.  Especially
> the
> if((k==m)or(k==n)or(v==m)or(v==n))
> (I tried (k or v) == (m or n) but didn't give the result I'd hoped for...)

Yeah.  How about:
if k in (m,n) or v in (m,n):
?
If you use the "in" trick, you don't really need to split out the tuples
in ListBUniqueEdges, so you can shorten it to
for x in ListBUniqueEdges:
  if k in x or v in x:

I feel that there should be something a little nicer, but I'm not
entirely sure what it is.  Is there any way of taking advantage of the
fact that the pairs are in some order?  I think there should be, but I
can't see it...

(I kind of want to write:
 if (k,v) in (m,n):
 but I know that's not going to work, and I don't think it should work,
 particularly.  Still, it would be nice.)

> >I can do it with a list comprehension, but I'ld like to see
> >what you came up with first...

The other trick I used was the dict() method, which takes a list of
tuples and turns them into a dictionary.  i.e.
>>> dict([(1,2),(3,4)])
{1: 2, 3: 4}

And finally, here's my list comprehension (a one-liner, even!) :
dict( [((a,b),[x for x in ListBUniqueEdges if a in x or b in x]) for a,b in ListAUniqueEdges] )
and the output:
{(3, 7): [(2, 7), (3, 5)], (2, 6): [(2, 7), (1, 6)], (8, 9): [], (1, 5): [(3, 5), (1, 6)]}

I don't think it's particularly more readable than your solution, though.

Later,
Blake.




More information about the Tutor mailing list