So, the other answers have given you code that will probably work, but I wanted to explain a general approach. This algorithm uses a stack to keep track of the next things that need to be generated, and continues generating until it reaches the maximum length that you've specified.
from collections import deque
from typing import Deque, Iterator, Optional
def generate_next_strings(chars: str, base: str = "") -> Iterator[str]:
# This function appends each letter of a given alphabet to the given base.
# At its first run, it will generate all the single-length letters of the
# alphabet, since the default base is the empty string.
for c in chars:
yield f"{base}{c}"
def generate_all_strings(chars: str, maxlen: Optional[int] = None) -> Iterator[str]:
# We "seed" the stack with a generator. This generator will produce all the
# single-length letters of the alphabet, as noted above.
stack: Deque[Iterator[str]] = deque([generate_next_strings(chars)])
# While there are still items (generators) in the stack...
while stack:
# ...pop the next one off for processing.
next_strings: Iterator[str] = stack.popleft()
# Take each item from the generator that we popped off,
for string in next_strings:
# and send it back to the caller. This is a single "result."
yield string
# If we're still generating strings -- that is, we haven't reached
# our maximum length -- we add more generators to the stack for the
# next length of strings.
if maxlen is None or len(string) < maxlen:
stack.append(generate_next_strings(chars, string))
You can try it using print("\n".join(generate_all_strings("abc", maxlen=5)))
.