Следующее появляется в моем коде Python 2.6:
for src, dst in ([s,d] for s in universe for d in universe if s != d):
Я могу сделать намного лучше? То, что я особенно не люблю, - то, что я в действительности указываю ту же пару дважды, однажды для для цикла и снова для выражения генератора. Я не уверен, предпочел ли я:
for src, dst in itertools.product(universe, universe):
if src != dst:
Существует ли способ выразить этот цикл кратко?
universe
оказывается, список, если это имеет какое-либо значение. Порядок повторения не имеет значения.
Вы можете использовать простые вложенные циклы for:
for src in universe:
for dst in universe:
if src == dst:
continue
...
Я бы сказал, что в данном случае это самый простой для чтения синтаксис.
Я предлагаю сохранить его полностью функциональным или полностью с пониманием. Вот полностью функциональная реализация.
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 может принимать аргумент ключевого слова «повтор», если вы хотите иметь ту же последовательность, что и несколько параметров:
itertools.product(universe, repeat=2)
это вопрос мнения относительно того, является ли это более читаемым.
Вы можете заменить исходный код на:
for (src, dest) in filter(lambda (a,b): a!=b, itertools.product(universe, repeat=2)):
...