2013-05-19 163 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) 
相關問題