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.
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.
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')
"""
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)):
...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With