How can I do itertools.product-controlled repetition of any character?

346 Views Asked by At

This is code with 8 repitios possible of all charaters

from itertools import *
for i in product(['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f'],repeat = 8):
    b = (''.join(i))
    print (b)

How can I do something like that - allow maximum 4 or 5 character repetition per 8-symbol string. As an example, 222abbccc or a3333abd.

Allow every symbol from the list to repeat from 1 to 4 times at any place in 8-symbol string, but keep working permutation and try not lose performance.

1

There are 1 best solutions below

14
Mark Tolonen On BEST ANSWER

A recursive function can implement additional rules above what product is producing. Realize that 16 characters with a repeat of 8 has ~4 billion results without a rep limit. The following function works but the example is limited for time:

from pprint import pprint

def generate(charset, length, maxrep):
    if length == 1:
        yield from charset
    else:
        for prefix in generate(charset, length - 1, maxrep):
            for char in charset:
                # Skip characters if the prefix already ends with the max rep
                if not prefix.endswith(char * maxrep):
                    yield prefix + char

pprint(list(generate('012',4,2)),compact=True)

Output:

['0010', '0011', '0012', '0020', '0021', '0022', '0100', '0101', '0102', '0110',
 '0112', '0120', '0121', '0122', '0200', '0201', '0202', '0210', '0211', '0212',
 '0220', '0221', '1001', '1002', '1010', '1011', '1012', '1020', '1021', '1022',
 '1100', '1101', '1102', '1120', '1121', '1122', '1200', '1201', '1202', '1210',
 '1211', '1212', '1220', '1221', '2001', '2002', '2010', '2011', '2012', '2020',
 '2021', '2022', '2100', '2101', '2102', '2110', '2112', '2120', '2121', '2122',
 '2200', '2201', '2202', '2210', '2211', '2212']