Combinations and Permutations are closely linked. The function shown here is a recursive generator function that returns permutations with selectable sample size ...
# a permutation or combination does not repeat sample items
# Python3 has a non-recursive combination function
# via itertools.combinations(iterable, sample_size)
# and a non-recursive permutation function
# via itertools.permutations(iterable, sample_size=None)
# vegaseat
def permutations(seq, n):
"""
permutations(seq, n) is a recursive generator function where
seq is an iterable object like a list or string
n is the sample size
returns a list of nonrepeating sample size items
n = len(seq) is the max sample size
"""
if n == 0:
yield []
else:
for k in range(len(seq)):
# a recursive function
for p in permutations(seq[:k] + seq[k+1:], n - 1):
yield [seq[k]] + p
def unique_combinations(seq, n):
"""
unique_combinations(seq, n) is a recursive generator function
where
seq is an iterable object like a list or string
n is the sample size
returns a list of nonrepeating sample size items
n = len(seq) is the max sample size
"""
if n == 0:
yield []
else:
for i in range(len(seq) - n + 1):
# recursion
for uc in unique_combinations(seq[i+1:], n - 1):
yield [seq[i]] + uc
iterable = 'abc'
sample_size = 2
perm_list = list(permutations(iterable, sample_size))
# show as a list of lists
print( perm_list )
print( '-'*40 )
# show as a list of strings
print( ["".join(item) for item in perm_list] )
print( '-'*40 )
comb_list = list(unique_combinations(iterable, sample_size))
# show as a list of lists
print( comb_list )
print( '-'*40 )
# show as a list of strings
print( ["".join(item) for item in comb_list] )
""" my result (sample size max - 1) -->
[['a', 'b'], ['a', 'c'], ['b', 'a'],
['b', 'c'], ['c', 'a'], ['c', 'b']]
----------------------------------------
['ab', 'ac', 'ba', 'bc', 'ca', 'cb']
----------------------------------------
[['a', 'b'], ['a', 'c'], ['b', 'c']]
----------------------------------------
['ab', 'ac', 'bc']
"""