Here is a simple working example:
from collections import defaultdict
from typing import List, Tuple
def string_key(string: str) -> Tuple[str, ...]:
"""Returns a key which is unique on the characters in the string (ignoring ordering)."""
return tuple(sorted(string))
def group_by_chars(data: List[str]) -> List[List[str]]:
"""Group strings by the characters they contain, regardless of order."""
result = defaultdict(list)
for value in data:
key = string_key(value)
result[key].append(value)
return list(result.values())
assert group_by_chars(["abc", "acb", "aab", "aba"]) == [["abc", "acb"], ["aab", "aba"]]
The trick is defining a function which maps values which belong to the same group to the same key, and putting each value into a bucket based on the output of that key function.
Another approach would be to use sorted
and itertools.groupby:
from itertools import groupby
from typing import List, Tuple
def string_key(string: str) -> Tuple[str, ...]:
"""Returns a key which is unique on the characters in the string (ignoring ordering)."""
return tuple(sorted(string))
def alternate_group_by_chars(data: List[str]) -> List[List[str]]:
result = []
for _key, group in groupby(sorted(data, key=string_key), string_key):
result.append(list(group))
return result
However this will return results in a different order (due to the necessary sorted
) and think its less readable.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…