Combinations Using Itertools Doesn’t Have To Be Hard

Hello Geeks! How are you? I hope all are doing great. So, today we are going to learn about itertools.combinations() method i.e. combinations using itertools. But before diving into the topic, it is important to understand its usage. Let’s take a look at it first.

So, when we go for some statical calculation, we often get in condition to permutations or combinations. However, we can calculate them on our own, but sometimes it is impossible to do that with big numbers. Now think, what if we have some tools that calculate it for us.

Itertools Module

Itertools module exactly does it for us. However, its scope is not limited to that only. It has more functions that make other statical work easy too. However, this module is divided into three sub-categories, i.e.

  • Infinite Iterators
  • Combinatoric Iterators
  • Terminating Iterators

As this module is quite significant to discuss in one go, we will focus only on the combinations() method. Before moving ahead, let’s see its installation, how we can import it, and what combinations are.

Installation

As this function is inbuilt in python, it does need any straightforward installation. You need to import it before using it. You can do it using the following command.

import itertools

What is Combinations?

So, talking about combinations, we can say that it is a technique of arranging a collection of items. In combinations, the order of items doesn’t matter, which means “ab” counts as the same as “ba”. In mathematics, the formula for calculating the number of combinations is as follows.

nCr = n!/(n-r)!(r)!

The meaning of the above formula is ‘ To arrange “r” elements from given “n” elements’ and is represented by ‘nCr’.

Itertools.Combinations()

The specific method is part of the combinatoric category of the itertools module. Other methods like permutations() and products() are part of this category. However, if we talk about the combinations() method, it generally deals with all possible combinations for the given data set.

More specifically, the presented method prints all the possible combinations of data without replacement. But, if we want to print all possible combinations with replacement, we can use the combinations_with_replacement() method. In both cases, the only point to note is that we need to pass the arguments in sorted order.

So till now, we understand its usage. Now, it is the time when we can see how to use it. So let’s move on to that.

Examples

Example 1: Combinations without replacements

In this example, we will see the possible number of combinations of 3 letter words from the letter “pythonpool”.

# Let's import combinations from itertools module
from itertools import combinations

# Now, we just try to find all the no. of possible combinations from letter pythonpool
word = 'pythonpool'
n = len(word)
print(n)

# Finding all possible combinations
combination = combinations(word,3)

y = [' '.join(i) for i in combination]
print(y)          #printing all the possible combinations
print(len(y))  #printing total numbers of items in the list.

Click here to learn how to import modules.

Output:

10
['p y t', 'p y h', 'p y o', 'p y n', 'p y p', 'p y o', 'p y o', 'p y l', 'p t h', 'p t o', 'p t n', 'p t p', 'p t o', 'p t o', 'p t l', 'p h o', 'p h n', 'p h p', 'p h o', 'p h o', 'p h l', 'p o n', 'p o p', 'p o o', 'p o o', 'p o l', 'p n p', 'p n o', 'p n o', 'p n l', 'p p o', 'p p o', 'p p l', 'p o o', 'p o l', 'p o l', 'y t h', 'y t o', 'y t n', 'y t p', 'y t o', 'y t o', 'y t l', 'y h o', 'y h n', 'y h p', 'y h o', 'y h o', 'y h l', 'y o n', 'y o p', 'y o o', 'y o o', 'y o l', 'y n p', 'y n o', 'y n o', 'y n l', 'y p o', 'y p o', 'y p l', 'y o o', 'y o l', 'y o l', 't h o', 't h n', 't h p', 't h o', 't h o', 't h l', 't o n', 't o p', 't o o', 't o o', 't o l', 't n p', 't n o', 't n o', 't n l', 't p o', 't p o', 't p l', 't o o', 't o l', 't o l', 'h o n', 'h o p', 'h o o', 'h o o', 'h o l', 'h n p', 'h n o', 'h n o', 'h n l', 'h p o', 'h p o', 'h p l', 'h o o', 'h o l', 'h o l', 'o n p', 'o n o', 'o n o', 'o n l', 'o p o', 'o p o', 'o p l', 'o o o', 'o o l', 'o o l', 'n p o', 'n p o', 'n p l', 'n o o', 'n o l', 'n o l', 'p o o', 'p o l', 'p o l', 'o o l']
120

In the above example, we haven’t sorted the alphabets, and hence alphabets appear in lexicographical ordering as the input string. But if we want to print the same in a sorted manner, we need to pass input in a sorted way. Moreover, in the above example, we have passes string as the first argument, but we also choose the passing list. Let’s check this one now.

Example 2 :

# Let's import combinations from itertools module
from itertools import combinations

# Now, we just try to find all the no. of possible combinations from letter pythonpool
word = 'pythonpool'
n = len(word)
print(n)

#sorting the strings in alphabetical order
sort_ = sorted(word)
# prints list of alphabets in sorted manner
print("Sorted array",sort_)
combination = combinations(sort_,3)
print()
y = [' '.join(i) for i in combination]
print(y)
print("Total possible combinations:",len(y))
Output:

Sorted array ['h', 'l', 'n', 'o', 'o', 'o', 'p', 'p', 't', 'y']

['h l n', 'h l o', 'h l o', 'h l o', 'h l p', 'h l p', 'h l t', 'h l y', 'h n o', 'h n o', 'h n o', 'h n p', 'h n p', 'h n t', 'h n y', 'h o o', 'h o o', 'h o p', 'h o p', 'h o t', 'h o y', 'h o o', 'h o p', 'h o p', 'h o t', 'h o y', 'h o p', 'h o p', 'h o t', 'h o y', 'h p p', 'h p t', 'h p y', 'h p t', 'h p y', 'h t y', 'l n o', 'l n o', 'l n o', 'l n p', 'l n p', 'l n t', 'l n y', 'l o o', 'l o o', 'l o p', 'l o p', 'l o t', 'l o y', 'l o o', 'l o p', 'l o p', 'l o t', 'l o y', 'l o p', 'l o p', 'l o t', 'l o y', 'l p p', 'l p t', 'l p y', 'l p t', 'l p y', 'l t y', 'n o o', 'n o o', 'n o p', 'n o p', 'n o t', 'n o y', 'n o o', 'n o p', 'n o p', 'n o t', 'n o y', 'n o p', 'n o p', 'n o t', 'n o y', 'n p p', 'n p t', 'n p y', 'n p t', 'n p y', 'n t y', 'o o o', 'o o p', 'o o p', 'o o t', 'o o y', 'o o p', 'o o p', 'o o t', 'o o y', 'o p p', 'o p t', 'o p y', 'o p t', 'o p y', 'o t y', 'o o p', 'o o p', 'o o t', 'o o y', 'o p p', 'o p t', 'o p y', 'o p t', 'o p y', 'o t y', 'o p p', 'o p t', 'o p y', 'o p t', 'o p y', 'o t y', 'p p t', 'p p y', 'p t y', 'p t y']
Total possible combinations: 120

Example 3: Combinations with replacement

In the output of both cases, we can see that the words haven’t been replaced during the arrangement. However, we also have a choice of replacement arrangements. We can do that with the combinations_with_replacement() method. Let’s see an example.

# Let's import combinations from itertools module
from itertools import combinations, combinations_with_replacement

# Now, we just try to find all the no. of possible combinations with replacement from letter pythonpool 
word = 'pythonpool'
n = len(word)
print(n)

# Finding all possible combinations
combination = combinations_with_replacement(word,3)

y = [' '.join(i) for i in combination]
print(y)
print(len(y))
Output:

10
['p p p', 'p p y', 'p p t', 'p p h', 'p p o', 'p p n', 'p p p', 'p p o', 'p p o', 'p p l', 'p y y', 'p y t', 'p y h', 'p y o', 'p y n', 'p y p', 'p y o', 'p y o', 'p y l', 'p t t', 'p t h', 'p t o', 'p t n', 'p t p', 'p t o', 'p t o', 'p t l', 'p h h', 'p h o', 'p h n', 'p h p', 'p h o', 'p h o', 'p h l', 'p o o', 'p o n', 'p o p', 'p o o', 'p o o', 'p o l', 'p n n', 'p n p', 'p n o', 'p n o', 'p n l', 'p p p', 'p p o', 'p p o', 'p p l', 'p o o', 'p o o', 'p o l', 'p o o', 'p o l', 'p l l', 'y y y', 'y y t', 'y y h', 'y y o', 'y y n', 'y y p', 'y y o', 'y y o', 'y y l', 'y t t', 'y t h', 'y t o', 'y t n', 'y t p', 'y t o', 'y t o', 'y t l', 'y h h', 'y h o', 'y h n', 'y h p', 'y h o', 'y h o', 'y h l', 'y o o', 'y o n', 'y o p', 'y o o', 'y o o', 'y o l', 'y n n', 'y n p', 'y n o', 'y n o', 'y n l', 'y p p', 'y p o', 'y p o', 'y p l', 'y o o', 'y o o', 'y o l', 'y o o', 'y o l', 'y l l', 't t t', 't t h', 't t o', 't t n', 't t p', 't t o', 't t o', 't t l', 't h h', 't h o', 't h n', 't h p', 't h o', 't h o', 't h l', 't o o', 't o n', 't o p', 't o o', 't o o', 't o l', 't n n', 't n p', 't n o', 't n o', 't n l', 't p p', 't p o', 't p o', 't p l', 't o o', 't o o', 't o l', 't o o', 't o l', 't l l', 'h h h', 'h h o', 'h h n', 'h h p', 'h h o', 'h h o', 'h h l', 'h o o', 'h o n', 'h o p', 'h o o', 'h o o', 'h o l', 'h n n', 'h n p', 'h n o', 'h n o', 'h n l', 'h p p', 'h p o', 'h p o', 'h p l', 'h o o', 'h o o', 'h o l', 'h o o', 'h o l', 'h l l', 'o o o', 'o o n', 'o o p', 'o o o', 'o o o', 'o o l', 'o n n', 'o n p', 'o n o', 'o n o', 'o n l', 'o p p', 'o p o', 'o p o', 'o p l', 'o o o', 'o o o', 'o o l', 'o o o', 'o o l', 'o l l', 'n n n', 'n n p', 'n n o', 'n n o', 'n n l', 'n p p', 'n p o', 'n p o', 'n p l', 'n o o', 'n o o', 'n o l', 'n o o', 'n o l', 'n l l', 'p p p', 'p p o', 'p p o', 'p p l', 'p o o', 'p o o', 'p o l', 'p o o', 'p o l', 'p l l', 'o o o', 'o o o', 'o o l', 'o o o', 'o o l', 'o l l', 'o o o', 'o o l', 'o l l', 'l l l']
220

Example 4: Itertools combinations for two lists

list1 = [1, 2, 3]
list2 = ['a', 'b']
all_combinations = []

# Selecting all possibility of two values from list 1
list1_permutations = permutations(list1, len(list2))

for each_permutation in list1_permutations:
    zipped = zip(each_permutation, list2)
    all_combinations.append(list(zipped))

print(all_combinations)
Output:

[[(1, 'a'), (2, 'b')], [(1, 'a'), (3, 'b')], [(2, 'a'), (1, 'b')], [(2, 'a'), (3, 'b')], [(3, 'a'), (1, 'b')], [(3, 'a'), (2, 'b')]]

Time Complexity

Talking about the time complexity of the combination function, we can say that to generate valid combinations exactly once, it will take O(n C r), and for getting r combinations, it is O(r). Hence, the total time complexity is O( r * [nCr]).

Itertools Combinations in Dataframes

Sometimes, we are in a condition in which we need to get combinations in pandas dataframes. We can make use of the lambda function to achieve it. Let’s see an example.

import pandas as pd
from itertools import combinations

# Creating a dataframe
df = pd.DataFrame({'Asset1':('a','e'), 'Asset2': ('b','f'), 'Asset3': ('c', 'g'),  'Asset4': ('d', 'h')})

# Adding a column named combinations in the dataframe to hold resultant combinations
df['combinations'] = df.apply(lambda r: list(combinations(r, 3)), axis=1)
print(df)

Output:

  Asset1 Asset2 Asset3 Asset4                                  combinations
0      a      b      c      d  [(a, b, c), (a, b, d), (a, c, d), (b, c, d)]
1      e      f      g      h  [(e, f, g), (e, f, h), (e, g, h), (f, g, h)]

BrainTeaser: Hackerrank Question

Task

You are given a string S. Your task is to print all the possible combinations of the string up to size k in lexicographically sorted order.

Input Format

A single line containing the string S and integer value k is separated by space.

Constraints

0 < k < len(S)

Output Format

Print the different combinations of string S on separate lines.

Sample Input

Hack 2

Sample Output

A
C
H
K
AC
AH
AK
CH
CK
HK

Solution

from itertools import combinations
i = input().split()
S = sorted(i[0])
k  = int(i[1]) 
combination = []
for x in range(1,k+1):
  combination += combinations(S,x)
  y = [''.join(i) for i in combination]
while y:
    print(y.pop(0))

Input:

Hack 2

Output:
A
C
H
K
AC
AH
AK
CH
CK
HK

Can we use iterations.combinations() with conditions

However, this function is convenient, and we can use it easily but, while solving a problem, we need to apply these functions over some conditions. So, is there any way to apply them to the given function? So, the answer to the given question is that although, we can’t apply any condition to them implicitly or as an argument. But what we can do is we will define some function explicitly which checks those conditions and then execute accordingly.

FAQs

Q1) Are itertools ordered combinations?

It is preferable to pass the lists or strings in an ordered way but is not compulsory. However, combinations results treat different orders as same having the same set of strings.

Q2) Is Itertools faster than for loop?

It is significantly faster than the “for” loop.

Conclusion

So, today in this article we read up about combination methods from the itertools module. We have seen its syntax, installation, and how we can import it into our program. Then, We have seen how can we use different data types such as strings or lists to build the combinations of other words using combination methods.

I hope this article helped you to get a better understanding of the combinations() method. Thank you

Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments