2012-05-10 63 views
1

我有一個列表:Python列表組合

nums = [1, 2, 3, 4] 

我想獲得一切準備分裂名單1 - 3

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

現在我能找到的最好的是使用itertools.combinations(num, 3),但它只會給每個項目的第二部分,這意味着[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]。有其他方法可以使用嗎?

回答

5

取決於你如何一般解題,該解決方案可以或多或少簡單:)

In [1]: nums = [1, 2, 3, 4] 

In [2]: [(x, tuple(y for y in nums if y != x)) for x in nums] 
Out[2]: [(1, (2, 3, 4)), (2, (1, 3, 4)), (3, (1, 2, 4)), (4, (1, 2, 3))] 

如果列表中有重複的值,請使用索引進行比較:

In [3]: [(x, tuple(y for j, y in enumerate(nums) if j != i)) for i, x in enumerate(nums)] 
Out[3]: [(1, (2, 3, 4)), (2, (1, 3, 4)), (3, (1, 2, 4)), (4, (1, 2, 3))] 
+0

好回答..... – himanshu

+0

不錯的做法,但如果有'nums'中有重複的值將不會工作。對於更通用的解決方案,請使用'enumerate'並比較索引。 –

+0

@Shawn,這是我想到的事情之一,當它說或多或少容易:)我已經添加了一個'枚舉'的例子,但它看起來並不漂亮。可以簡化嗎? –

2

你在這裏一半。您可以將結果與使用zipreversed您最初的名單結合起來:

result = zip(num, reversed(itertools.combinations(num, 3))) 

但是,如果你要使用的第一部分是某種指數的唯一,也沒有必要。您可以使用列表中元素的位置作爲索引(顯然)。

+0

感謝,我不希望使用第一部分爲指標。 – wong2

+0

感謝您的更新,但訂單沒有必要 – wong2

+0

你是什麼意思命令沒有必要?它看起來像第一部分中的數字總是不在第二部分列表中的數字。這不正確嗎?要做到這一點,你必須正確地將兩個列表組合在一 –

0

這是卓有成效的,但可能是低效的:

>>> t=set(nums) ; [ (t.difference(x).pop(),x) for x in list(itertools.combinations(t,3)) ] 
[(4, (1, 2, 3)), (3, (1, 2, 4)), (2, (1, 3, 4)), (1, (2, 3, 4))] 
2

這看起來比較簡單lution:

nums = [1, 2, 3, 4] 
for n in range(len(nums)): 
    print (nums[n], nums[:n] + nums[n+1:]) 

的理解:

result = [(s, nums[:n] + nums[n+1:]) for n, s in enumerate(nums)] 
+0

內部集合是一個列表而不是一個元組,如OP示例中所示,但如果它很重要,那麼修復這個問題是微不足道的。好的解決方案 –

+0

@ShawnChin:是的,'tuple()'故意留給讀者練習)) – georg