The itertools module in Python provides a set of functions for working with iterables to produce complex and efficient iterators.

The combinations() function in the module is a powerful tool for generating possible non-repeating combinations of elements from an iterable.  In mathematics, combinations are subsets of an original set, where the order of elements does not matter. This means that combinations {'A', 'B'} and  {'B', 'A'} are considered to be the same.

combinations(iterable, r)
iterable Required. An iterable object whose combinations we want.
r Required. Represents the size of different combinations that are possible. The function returns only the combinations with a  length of r. Where  0 < r <= len(iterable)

The function returns an iterator of  tuples in which each tuple's elements are a possible r-length combination of the original iterable.

from itertools import combinations

names = ["Bob", "Alice", "John", "Sara"] 

combs = combinations(names, 2)

for comb in combs: 
      print(comb) 

The following example shows how we can get all possible combinations of the target iterable using a for loop.

from itertools import combinations

data = 'ABC'

for i in range(len(data)):
    for comb in combinations(data, i + 1):
        print(comb)