生成器表达式与for循环的糟糕组合
在我的Python 2.6代码中出现了以下内容:
for src, dst in ([s,d] for s in universe for d in universe if s != d):
我能做得更好吗?我特别不喜欢的是,我实际上是把同一对值指定了两次,一次是在for循环中,另一次是在生成器表达式中。我不确定我是否更喜欢:
for src, dst in itertools.product(universe, universe):
if src != dst:
有没有办法更简洁地表达这个循环?
universe
恰好是一个列表,如果这有什么区别的话。迭代的顺序并不重要。
3 个回答
1
itertools.product 可以接受一个叫做 "repeat" 的参数,如果你想让同样的序列作为多个参数使用的话。
itertools.product(universe, repeat=2)
这是否更容易理解,见仁见智。
你可以用下面的代码替换你原来的代码:
for (src, dest) in filter(lambda (a,b): a!=b, itertools.product(universe, repeat=2)):
...
3
我建议要么完全使用函数式编程,要么完全使用列表推导式。下面是一个完全使用函数式编程的实现方式。
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')
"""
5
你可以使用简单的嵌套for循环:
for src in universe:
for dst in universe:
if src == dst:
continue
...
我觉得在这种情况下,这种写法是最容易理解的。