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
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.
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