Steve Jessop
Steve Jessop

Reputation: 279285

Ugly combination of generator expression with for loop

The following appears in my Python 2.6 code:

for src, dst in ([s,d] for s in universe for d in universe if s != d):

Can I do much better? What I particularly don't like is that I'm in effect specifying the same pair twice, once for the for loop and again for the generator expression. I'm uncertain whether I'd prefer:

for src, dst in itertools.product(universe, universe):
    if src != dst:

Is there a way to express this loop concisely?

universe happens to be a list, if it makes any difference. Order of iteration doesn't matter.

Upvotes: 8

Views: 912

Answers (3)

Dave Kirby
Dave Kirby

Reputation: 26552

itertools.product can take a "repeat" keyword argument if you want to have the same sequence as more than one parameter:

itertools.product(universe, repeat=2)

it is a matter of opinion as to whether this is more readable.

You could replace your original code with:

for (src, dest) in filter(lambda (a,b): a!=b, itertools.product(universe, repeat=2)):
    ...

Upvotes: 1

Jason R. Coombs
Jason R. Coombs

Reputation: 42689

I suggest keeping it entirely functional or entirely with comprehensions. Here's an implementation that's entirely functional.

import itertools 
import operator

def inner_product(iterable):
    "the product of an iterable with itself"
    return itertools.product(iterable, repeat=2)

def same(pair):
    "does this pair contain two of the same thing?"
    return operator.is_(*pair)

universe = 'abcd'

pairs = inner_product(universe)
unique_pairs = itertools.ifilterfalse(same, pairs)
for pair in unique_pairs:
    print pair

"""
('a', 'b')
('a', 'c')
('a', 'd')
('b', 'a')
('b', 'c')
('b', 'd')
('c', 'a')
('c', 'b')
('c', 'd')
('d', 'a')
('d', 'b')
('d', 'c')
"""

Upvotes: 3

sth
sth

Reputation: 229663

You could use simple nested for-loops:

for src in universe:
   for dst in universe:
      if src == dst:
         continue
      ...

I'd say this is the most easy to read syntax in this case.

Upvotes: 5

Related Questions