wong2
wong2

Reputation: 35720

Python list combination

I have a list:

nums = [1, 2, 3, 4]

I'd like to get all the possibilities to split the list 1 - 3:

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

Now the best I can find is use itertools.combinations(num, 3), but it will only give the second part of each item, that means [(1, 2, 3), (1, 2, 4), (1, 3, 4), (2, 3, 4)]. are there other methods I can use?

Upvotes: 1

Views: 345

Answers (4)

Lev Levitsky
Lev Levitsky

Reputation: 65791

Depending on how general the problem you're solving is, the solution can be more or less simple :)

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))]

If there are repeating values in the list, use indices for comparison:

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))]

Upvotes: 6

georg
georg

Reputation: 214959

This appears to be a simpler solution:

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

as a comprehension:

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

Upvotes: 2

Vlad
Vlad

Reputation: 18633

This does the trick but is probably inefficient:

>>> 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))]

Upvotes: 0

Felix Kling
Felix Kling

Reputation: 816404

You are halfway there. You can combine the result with your original list using zip and reversed:

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

But if you want to use the first part is some kind of index only, there is no need for that. You can use the position of the element in the list as index (obviously).

Upvotes: 2

Related Questions