How to apply Python generators to finding min and max values?
eval(...)

What is the purpose of:

compilt = "r'(?=(" + genes[i] + "))'"
... eval(compilt), ...


It takes a string like "aa", and forms a new string "r'(?=(aa))'", which is source code for the raw string r'(?=(aa))', which when evaluated yields the string "(?=(aa))".

There is no escaping being done, no obvious reason to do the raw string formation and subsequent evaluation, and no prevention of a syntax error due to a stray ' character in the genes[i] array.  So ... why not simply:

regex = "(?=(" + gene[i] + "))"


and no call to eval(...) at all?

Regex Capturing

The regex subexpression (...) is a "capturing group", which copies the matching characters into an internal buffer, for returning in the match group.

&gt;&gt;&gt; re.findall('(?=(aa))', "caaab")
['aa', 'aa']


Without the capturing group, the matching characters do not have to be copied to the internal buffer, to be returned.

&gt;&gt;&gt; re.findall('(?=aa)', "caaab")
['', '']


Given that you are only interested in the len(...) of the list returned from re.findall(), the capturing group seems like unnecessary overhead, which can be eliminated for faster execution.

Compiled Regex

As Python uses regular expressions, it maintains a cache of the most recently used regular expressions.  This cache has a limited size, to prevent an excessive memory load.

In this exercise, you are repeatedly using the same gene regular expressions for each "healthy string" test.  If the number of genes exceeds the cache size, Python will be tossing out compiled regular expressions, only to compile them again moments later.

You can preempt this by compiling and storing all the gene regular expressions ahead of time.  Leveraging Python 3.6's f-strings, and list comprehension:

    genes = input().rstrip().split()
    genes_rx = [re.compile(f"(?={gene})") for gene in genes]


Used as:

               matches = len(re.findall(genes_rx[i], gn))


Now the gene to regular expression string, to compiled regular expression is done once per gene, instead of once per "healthy string" test.

Computing min/max weight without creating a list

How about:

    min_weight = math.inf
    max_weight = -math.inf

    for ...:

        weight = ...

        if weight &lt; min_weight:
            min_weight = weight
        if weight &gt; max_weight:
            max_weight = weight

    print(min_weight, max_weight)