I am trying to extend the code from the top answer here:
Find all the possible N-length anagrams - fast alternatives
I need to do the same thing, but to yield all sub-anagrams (without repetition).
Most questions on this subject treat only input strings like "ABCD"
where the characters are all unique.
EXAMPLE
Input = "abb"
Expected output is an iterator that yields from
["a", "b", "ab", "ba", "bb", "abb", "bab", "bba"]
So, for instance, "bba"
isn't yielded twice as a result of there being two "b"
occurences in the input string.
The following code does what I want:
from itertools import permutations, chain
from typing import Iterator
def shuffler(word: str) -> Iterator[str]:
yield from set(chain(
*map(
lambda x:
permutations(word, x), range(1, len(word) + 1)
)
))
This code first creates a set, however. As I will be using this function many thousands of times, the code will be slower than if a "pure" iterator were returned from the function.