Regular Expressions - finding two or more vowels with a consonant before and after it, includes overlapping Is there a way to make my code more compact or efficient?

Testcase example 1 : rabcdeefgyYhFjkIoomnpOeorteeeeet
output:
ee
Ioo
Oeo
eeeee

Testcase example 2 : baabooteen
output:
aa
oo
ee

import re
def find_two_or_more_vowels(string: str):
    match_obj = list(re.finditer(r'(?&lt;=[qwrtypsdfghjklzxcvbnm])([aeiou]{2,})(?=[qwrtypsdfghjklzxcvbnm])', string, re.IGNORECASE))
    if len(list(match_obj)) != 0:
        for match in match_obj:
            print(match.group())
    else:
        print(-1)


find_two_or_more_vowels(input())
Raw Strings

 r'(?&lt;=[qwrtypsdfghjklzxcvbnm])([aeiou]{2,})(?=[qwrtypsdfghjklzxcvbnm])'


The advantage of raw strings is you don't have to escape (add a \ before) certain characters, such as quotation marks and the backslash character itself.  You aren't using any characters you need to escape here, so why use a raw string?  

Redundant lists

match_obj = list(...)
if len(list(match_obj)) != 0:
    ...


match_obj is already a list; you don't need to make a new list out of it, to determine it's length.  Just use match_obj directly:

match_obj = list(...)
if len(match_obj) != 0:
    ...


Of course, a list of length zero is falsy, and any list of non-zero length is truthy, so you don't need the len(...) != 0 test:

match_obj = list(...)
if match_obj:
    ...


list(re.finditer)

The function re.finditer(...) returns an iterator, and avoids building up the complete result, so you can process a string piece by piece, distributing the memory usage over time instead of collecting and returning all results immediately.

Passing the result of re.finditer(...) to list(...) immediately runs the iterator to completion, collecting all results into the in-memory list.  Any efficiency gained by using the iterator version is lost, and may actually decrease performance because the work required to create the iterator, save temporary state, etc., has been wasted.

The only thing you do with the resulting match objects is call .group() on them, to get the matched text.

So why not use re.findall(...) which returns the list of matched strings?

    matches = re.findall(r'(?&lt;=[qwrtypsdfghjklzxcvbnm])([aeiou]{2,})(?=[qwrtypsdfghjklzxcvbnm])', string, re.IGNORECASE))
    if matches:
        for match in matches:
            print(match)
    else:
        print(-1)


Consonants

This isn't going to make the code more compact or efficient, but it might make it more maintainable and readable:

Is "qwrtypsdfghjklzxcvbnm" the complete list of consonants?  Did you forget any?  You've ordered them in QWERTY order, which makes it hard for a reader to verify it.

Sometimes "y" is considered a vowel.  If you were to want to include it, you'd have to add the "y" to the vowel list, and remove it twice from the consonants list.

Maybe you should:

from string import ascii_lowercase

vowels = "aeiou"
consonants = ''.join(set(ascii_lowercase) - set(vowels))


Then you could generate your regex string:

double_vowels = f"(?&lt;=[{consonants}])([{vowels}]{{2,}})(?=[{consonants}])"


and even compile it:

double_vowels = re.compile(
    f"(?&lt;=[{consonants}])([{vowels}]{{2,}})(?=[{consonants}])",
    re.IGNORECASE)


Refactored Code

import re
from string import ascii_lowercase

vowels = "aeiou"
consonants = ''.join(set(ascii_lowercase) - set(vowels))

double_vowels = re.compile(
    f"(?&lt;=[{consonants}])([{vowels}]{{2,}})(?=[{consonants}])",
    re.IGNORECASE)

def find_two_or_more_vowels(string: str) -&gt; None:
    matches = double_vowels.findall(string)
    if matches:
        for match in matches:
            print(match)
    else:
        print(-1)

if __name__ == '__main__':
    find_two_or_more_vowels(input())