Python Forum

Full Version: permutations of varying length
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
i need to create permutations of N letters. but i also need all lengths in range(1,N+1), N just happens to also be the number of letters to be permuted? what is this kind of permutation called? is there a way to do this in itertools? or do i need to chain a bunch of permute() iterators of varying length? i know a way to do this but i am unsure of the best way in Python.
These kinds of permutations are called «Arrangements» in classical mathematical literature (although there may be more modern terms to refer to them) See the paragraph about k-permutations of n here https://en.wikipedia.org/wiki/Permutatio...tions_of_n (note that these are only the 'restricted partial premutations' in https://en.wikipedia.org/wiki/Partial_pe...rmutations)

The following piece of code should do the trick
s = "abcde"                               
n = len(s)                                 
seq = (a for i in range(1, n+1) for c in itt.combinations(s, i) for a in itt.permutations(c, i))                                       
                                           
for x in seq:                             
    print(x)
i was using chain().

if there is a more modern term, i'd expect wikipedia to have it.

i'm also doing this as a combination of two sets of permutations to make a variety of command symlinks. here is the code i have done, so far:
from itertools import chain, permutations

s1 = 'eio' # characters for name base
s2 = 'al'  # characters for name suffix

# combine all permutations of base and suffix
# and also without a suffix

# these combinations are excluded
ex = ('e','eio')

def vlp(s):
    """Varying length permutations chained together, 1 to max (inclusive)."""
    return chain(*[permutations(s,n)for n in range(1,len(s)+1)])

a = [x for x in vlp(s1)]
b = [()] + [x for x in vlp(s2)] # include [()] so there is an empty case in suffixes
p = [x+y for x in a for y in b] # join all combinations including the empty suffix
n = [''.join(x) for x in p if ''.join(x) not in ex] # make strings and do excludes

# print all the nammes and how many
print(' '.join(sorted(n)))
print(len(n))
i'd like to find a way to do that comprehension in line 19 coding ''.join(x) only once.
This perhaps?
import itertools as itt

s1 = 'eio' # characters for name base
s2 = 'al'  # characters for name suffix
 
# combine all permutations of base and suffix
# and also without a suffix
 
# these combinations are excluded
ex = ('e', 'eio')
 
def vlp(s, start=0):
    """Varying length permutations chained together, start to max (inclusive)."""
    return itt.chain.from_iterable(
        itt.permutations(s, n) for n in range(start, len(s) + 1))

n = [z for z in (
        ''.join(x + y) for x, y in itt.product(
                        vlp(s1, 1), vlp(s2))) if z not in ex]
 
# print all the nammes and how many
print(' '.join(sorted(n)))
print(len(n))
it works, but i will need to study it a while to understand all the changes.