2013-05-19 254 views
1

作为学习Python的一部分,我已经给自己设定了一些挑战,以了解各种做事方式。我目前面临的挑战是使用列表理解来创建一个列表对。第一部分是制定一个列表,其中(x,y)不能相同(x不等于y)和顺序重要性((x,y)不等于(y,x))。检查组合是否已经从列表理解中存在

return [(x,y) for x in listOfItems for y in listOfItems if not x==y] 

利用我现有的代码,是否可以修改它,如果(X,Y)已经在列表中存在的(Y,X)从结果中排除了吗?我知道我可以在单词之后比较项目,但我想看看您对列表理解有多少控制。

我正在使用Python 2.7。

回答

2

你应该在这里使用一个发电机功能:

def func(listOfItems): 
    seen = set() #use set to keep track of already seen items, sets provide O(1) lookup 
    for x in listOfItems: 
     for y in listOfItems: 
      if x!=y and (y,x) not in seen: 
       seen.add((x,y)) 
       yield x,y 

>>> lis = [1,2,3,1,2] 
>>> list(func(lis)) 
[(1, 2), (1, 3), (1, 2), (2, 3), (1, 2), (1, 3), (1, 2), (2, 3)] 
+0

到产量如何工作的unique_everseen食谱我很好奇(因为我的避风港没有在代码中使用它)。 – RMDan

+0

@RMDan'yield'将普通函数转换为生成器,它们用于懒惰评估。阅读更多关于[生成器](http://wiki.python.org/moin/Generators)的信息。 –

+0

虽然没有我期望的答案,但它更好。教我关于Python的新东西,以及更清晰的代码编写方法。 – RMDan

1
def func(seq): 
    seen_pairs = set() 
    all_pairs = ((x,y) for x in seq for y in seq if x != y) 
    for x, y in all_pairs: 
     if ((x,y) not in seen_pairs) and ((y,x) not in seen_pairs): 
      yield (x,y) 
     seen_pairs.add((x,y)) 

另外,您也可以使用generator expression(这里:all_pairs),这是像列表解析,但懒惰的评估。他们是非常有帮助,特别是迭代组合时,products

0

使用productifilter以及来自itertools

>>> x = [1, 2, 3, 1, 2] 
>>> x = product(x, x) 
>>> x = unique_everseen(x) 
>>> x = ifilter(lambda z: z[0] != z[1], x) 
>>> for y in x: 
...  print y 
... 
(1, 2) 
(1, 3) 
(2, 1) 
(2, 3) 
(3, 1) 
(3, 2) 
相关问题