Home > Net >  Generating all possibilities of a string given a list of chars but want only the strings up to n len
Generating all possibilities of a string given a list of chars but want only the strings up to n len

Time:08-04

I have written the below code to recursively generate all of the possible combinations of a string.

def gen_recur(chr_lst, length, n , s, ls):
    
    if (n == 0):
        ls.append(s)
        return

    for j in range(0, length):
        str_app = s   chr_lst[j]
        gen_recur(chr_lst, length, n-1, str_app, ls)
    return

def generate_passwords(chr_str, length, ls):
    chr_lst = [char for char in chr_str]
    s = ""
    for n in range(1, length   1):
        gen_recur(chr_lst, length, n, s, ls)

if __name__ == "__main__":
    chr_str = 'abc'
    length = len(chr_str)
    ls = []
    generate_passwords(chr_str, length, ls)
    print(ls)

However I want to only produce all the possibilities of the string up to a length of n. Say the string is 'abc', and n=2. Instead of outputting all of the possible strings of 'abc' I only want to output the possible strings that are <= n in length.

Current output appears as.

['a', 'b', 'c', 'aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc', 'aaa', 'aab', 'aac', 'aba', 'abb', 'abc', 'aca', 'acb', 'acc', 'baa', 'bab', 'bac', 'bba', 'bbb', 'bbc', 'bca', 'bcb', 'bcc', 'caa', 'cab', 'cac', 'cba', 'cbb', 'cbc', 'cca', 'ccb', 'ccc']

However ideal output when n = 2 would appear as.

['a', 'b', 'c', 'aa', 'ab', 'ac', 'ba', 'bb', 'bc', 'ca', 'cb', 'cc']

When I change length to 2 then the output is:

['a', 'b', 'aa', 'ab', 'ba', 'bb']

And when I change the length to 4 I get a list index out of range error as expected due to the way I am indexing the list in the functions.

CodePudding user response:

You can use itertools.permutations:

from itertools import permutations

def generate_passwords(chr_str, length):
    for i in range(1, length 1):
        yield from map("".join, permutations(chr_str, i))

print(list(generate_passwords('abc', 2)))

CodePudding user response:

The best way is use a library as @trincot answered, but obiously always exist a solution, you need consider a limit variable to control when break the output

def gen_recur(chr_lst, length, n , s, limit):

if (len(s) > limit):
  return

if (n == 0):
  print(s)
  return

for j in range(0, length):
    str_app = s   chr_lst[j]
    gen_recur(chr_lst, length, n-1, str_app, limit)
return

def generate_passwords(chr_str, length, limit):
    chr_lst = [char for char in chr_str]
    s = ""
    for n in range(1, length   1):
        gen_recur(chr_lst, length, n, s, limit)

if __name__ == "__main__":
   chr_str = 'abc'
   limit = 2
   length = len(chr_str)
   generate_passwords(chr_str, length, limit)
  • Related