from typing import List, Set, Iterator
from collections import Counter, defaultdict
'''
def get_words(d: dict) -> List[str]:
words = []
for value in d.values():
if isinstance(value, dict):
words.extend(get_words(value))
else:
words.append(value)
return words
'''
'''
def find_unique(d: dict) -> Set[str]:
words = get_words(d)
c = Counter(words)
unique = set()
for word, n in c.items():
if n == 1:
unique.add(word)
return unique
'''
'''
def find_unique(d: dict) -> Set[str]:
return {word for word, n in Counter(get_words(d)).items() if n == 1}
'''
'''
def get_words(d: dict) -> List[str]:
words = []
def get_all(d: dict) -> None:
for value in d.values():
if isinstance(value, dict):
get_all(value)
else:
words.append(value)
get_all(d)
return words
'''
'''
def get_words(d: dict) -> Iterator[str]:
for value in d.values():
if isinstance(value, dict):
for v in get_words(value):
yield v
else:
yield value
'''
def get_words(d: dict) -> Counter:
c = Counter()
def get_all(d: dict) -> None:
for value in d.values():
if isinstance(value, dict):
get_all(value)
else:
c[value] += 1
get_all(d)
return c
def find_unique(d: dict) -> Set[str]:
return {word for word, n in get_words(d).items() if n == 1}
dicts = (
{10: 'hello', 20: 'hi'},
{10: 'hello', 20: 'hi', 30: 'hi'},
{10: 'hello', 20: 'hi', 30: {2: 'hi', 7: 'you'}},
{10: 'hello', 20: 'hi', 30: defaultdict(str, {2: 'hi', 7: 'you'})},
)
for d in dicts:
print(find_unique(d))