1

我有一个清单:

nums = [1, 2, 3, 4]

我想获得拆分列表的所有可能性1 - 3

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

现在我能找到的最好的是 use itertools.combinations(num, 3),但它只会给出每个项目的第二部分,这意味着[(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]. 我可以使用其他方法吗?

4

4 回答 4

6

根据您要解决的问题的一般性,解决方案可能或多或少简单:)

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))]
于 2012-05-10T10:06:46.547 回答
2

你已经成功了一半。您可以使用 and 将结果与原始列表结合zip起来reversed

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

但是如果你想使用第一部分只是某种索引,那就没有必要了。您可以使用列表中元素的位置作为索引(显然)。

于 2012-05-10T09:58:59.197 回答
2

这似乎是一个更简单的解决方案:

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)]
于 2012-05-10T10:12:59.273 回答
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))]
于 2012-05-10T10:05:53.287 回答