2013-03-30 89 views
2

只是一個樣式問題:是否有一種內置方法來獲取交換屬性斷言下的組合並排除與其自身配對的元素?兩個列表元素的交換組合

a = ["1", "2", "3"] 
b = ["1", "2", "3"] 
seen = [] 
combinations = [] 

for v1 in a: 
    for v2 in b: 
     if v1 != v2: 
      if (v2, v1) not in seen: 
       combinations.append((v1, v2)) 
       seen.append((v1, v2)) 

>> [('1', '2'), ('1', '3'), ('2', '3')] 

似乎不是很Python。我知道itertools.product是笛卡爾產品。我可以將它轉換成一個會排除身份配對的集合,但它仍然是不可交換的產品。

+0

如果你有'a = [1,2,3]; b = [4,5,6]',是否是(5,6)'輸出或不輸出?你可以從同一個列表中抽兩次嗎? (上面的代碼表示否) – DSM

回答

2

itertools.combinations,如果兩個列表都與此處相同。 或者在一般情況下itertools.product,其次是一些過濾:

In [7]: a = ["1", "2", "3"] 
    ...: b = ["a", "b", "c"] 

In [8]: list(filter(lambda t: t[0] < t[1], product(a,b))) 
Out[8]: 
[('1', 'a'), 
('1', 'b'), 
('1', 'c'), 
('2', 'a'), 
('2', 'b'), 
('2', 'c'), 
('3', 'a'), 
('3', 'b'), 
('3', 'c')] 

另外,我覺得術語組合已經意味着元素在結果中的順序並不重要。


好吧,Theodros是對的。對於補償,這裏應該列出的任何清單開展工作的一個版本:

l = [['1','2','3'], ['a','b'], ['x','y']] 

set(tuple(sorted(p)) for p in product(*l) if len(set(p)) > 1) 

給(適當排序)

set([('1', 'a', 'x'), 
    ('3', 'a', 'y'), 
    ('2', 'b', 'y'), 
    ('2', 'a', 'y'), 
    ('1', 'a', 'y'), 
    ('1', 'b', 'y'), 
    ('2', 'a', 'x'), 
    ('3', 'b', 'y'), 
    ('1', 'b', 'x'), 
    ('2', 'b', 'x'), 
    ('3', 'a', 'x'), 
    ('3', 'b', 'x')]) 

而且它也適用於以前的反l = [[1,2,3], [1,3,4,5]]

set([(1, 2), (1, 3), (1, 4), (1, 5), (2, 3), (2, 5), (3, 4), (2, 4), (3, 5)]) 
+0

-1,這不適用於'a = [1,3,4,5]'和'b = [1,2,3]' –

+0

@TheodrosZelleke正確。我已經更新了我的答案。編輯:好吧,還有一個錯誤...今天不是我的一天。 – phg

+0

@phg:你當前的版本可以返回太小的元組(例如'l = [['1','2','3'],['1','2','3'],['1 ','2','3']]')。我認爲'len(s)> 1'必須是'len(s)== len(l)'或類似的東西。 – DSM

-1

您的意思是?

a = ["1", "2", "3"] 
b = ["1", "2", "3"] 
print [(x,y) for x in a for y in b] 

輸出:

[('1', '1'), ('1', '2'), ('1', '3'), ('2', '1'), ('2', '2'), ('2', '3'), ('3', '1'), ('3', '2'), ('3', '3')] 
+1

這包括OP不希望'('1','2')':'('2','1')'的模糊。此外,可以用itertools複製:'[我爲我在列表中(itertools.product(a,b))如果我[0]!= i [1]]' – TerryA

+0

@Haidro。 .ok現在看到..接受的答案。 。和我一樣,但沒有'x!= y' – namit

+1

接受的答案根本不像你的。它在OP的情況下給出了[('1','2'),('1','3'),('2','3')] ('1','2'),('1','3'),('2','1'),('2','3'),('3',' 1'),('3','2')]'。 – DSM

1

假設ab是相同的。

>>> import itertools 
>>> a = ["1", "2", "3"] 
>>> list(itertools.combinations(a,2)) 
[('1', '2'), ('1', '3'), ('2', '3')] 
1

如果你不關心結果元組中的排序沒有映射到輸入列表(你不關心(1,2)還是(1,2)(2,1))。在這裏你可以用較小的元素得到組合第一:

a = [1,2,3] 
b = [1,3,4,5] 

set([(min(x,y), max(x,y)) for x in a for y in b if x != y]) 

set([(1, 2), 
    (1, 3), 
    (1, 4), 
    (1, 5), 
    (2, 3), 
    (2, 5), 
    (3, 4), 
    (2, 4), 
    (3, 5)]) 

用繩子

a = '1 2 3'.split() 
b = '1 3 4 5'.split() 

set([('2', '3'), 
    ('3', '5'), 
    ('1', '4'), 
    ('3', '4'), 
    ('1', '5'), 
    ('1', '2'), 
    ('2', '5'), 
    ('1', '3'), 
    ('2', '4')]) 

中的明顯差異訂購com es來自字符串和數字的不同哈希值。