# (mask, min, max) occ = [("?d", 0, 3), ("?l", 3, 5), ("?u", 1, 1), ("?s", 0, 2)] pwlen = [8, 9] from collections import OrderedDict def getMasks(occurrences, length, depth=0): char, min, max = occurrences.pop(0) char = [char] results = [] for combination in range(min, max+1): if not occurrences: results += [char*combination] else: res = getMasks(occurrences[:], length-combination, depth+1) if res is not None: results += list(map(lambda apx: char*combination + apx, res)) if occurrences and not list(filter( lambda x: True if len(x) == length else False, results)): return None return results masks = [] for pwl in pwlen: masks += getMasks(occ[:], pwl) masks = filter(lambda msk: True if len(msk) in pwlen else False, masks) masks = map(lambda x: "".join(x), masks) masks = OrderedDict.fromkeys(masks) for m in masks: print(m)