minhaj
minhaj

Reputation: 108

Python itertools combinations customizing

I am doing a question based on combinations and just stuck in it. And yes I am not so good in python.

The itertools combinations function using ncr just return the r possible combinations from n. I want something which will return the r possible combinations selected and also the other remaining elements from n numbers which were not selected in that iteration.

Example:

>>>from itertools import combinations
>>>list = [1, 2, 3, 4, 5]
>>>rslt = combinations(list, 2)

when [2, 4] is selected it should also return [1, 3, 5] so it should return like [[2, 4], [1, 3, 5]]

Thanks in advance

Upvotes: 2

Views: 1194

Answers (4)

user9614724
user9614724

Reputation: 3

You can avoid loops and improve readability by using sets, as such:

from itertools import combinations

input = [1,2,3,4,5]

for n in itertools.combinations(input, 2):
    print(n , set(n) ^ set(input))

That is, of course, assuming there are no duplicates in the original, which will be lost in the conversion to a set.

Upvotes: 0

Paul Panzer
Paul Panzer

Reputation: 53029

One slightly extravagant but fun way would be to use combinations twice:

from itertools import combinations
n = 5
k = 2
lst = list(range(1, n+1))
rslt = zip(combinations(lst, k), map(tuple, reversed(list(combinations(lst, n-k)))))
print(list(rslt))
# -> [((1, 2), (3, 4, 5)), ((1, 3), (2, 4, 5)), ((1, 4), (2, 3, 5)),
#     ((1, 5), (2, 3, 4)), ((2, 3), (1, 4, 5)), ((2, 4), (1, 3, 5)),
#     ((2, 5), (1, 3, 4)), ((3, 4), (1, 2, 5)), ((3, 5), (1, 2, 4)),
#     ((4, 5), (1, 2, 3))]

Upvotes: 1

The simplest way would be to make a copy of the original list, removing the elements that are in the combination:

from itertools import combinations
def combinations_and_remaining(l, n):
    for c in combinations(l, n):
        diff = [i for i in l if i not in c]
        yield c, diff 

for i in combinations_and_remaining([1, 2, 3, 4, 5], 2):
    print(i)

Will output

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

(The combinations returns tuples; remaining elements are returned as lists for efficiency)

Upvotes: 1

McGrady
McGrady

Reputation: 11477

itertools.combinations

Return r length subsequences of elements from the input iterable.

You can use a list comprehension to get the other items [j for j in l if j not in i]:

from itertools import combinations

l = [1, 2, 3, 4, 5]

for i in combinations(l,2):
    print(list(i),[j for j in l if j not in i])

And you will get :

[1, 2] [3, 4, 5]
[1, 3] [2, 4, 5]
[1, 4] [2, 3, 5]
[1, 5] [2, 3, 4]
[2, 3] [1, 4, 5]
[2, 4] [1, 3, 5]
[2, 5] [1, 3, 4]
[3, 4] [1, 2, 5]
[3, 5] [1, 2, 4]
[4, 5] [1, 2, 3]

By the way, it's not recommended to use list as a variable name.

Upvotes: 1

Related Questions