生成器表达式与for循环的糟糕组合

8 投票
3 回答
903 浏览
提问于 2025-04-15 19:51

在我的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
      ...

我觉得在这种情况下,这种写法是最容易理解的。

撰写回答