from collections import Iterable def unique(seq): """Return a new sequence made of unique elements from seq.""" uniques = [] [uniques.append(x) for x in seq if not uniques.count(x)] return type(seq)(uniques) class StrType: """Helper class to print and compare object types. __eq__ implemented to allow for StrType enumaration __hash__ implemented for compatibility with set objects __repr__ and __str__ to print type(StrType.obj) as desired. """ def __init__(self, obj): """Provide the object whose type you want to print.""" self.obj = obj def __eq__(self, other): if not isinstance(other, StrType): return False return type(self.obj) == type(other.obj) def __hash__(self): return hash(str(self)) def __str__(self): return f"<{type(self.obj).__name__}>" def __repr__(self): return self.__str__() def get_structure(data): """Return a kind of map of the could-be nested data. Duplicates are removed from sequences. """ if isinstance(data, dict): return {key:get_structure(value) for key, value in data.items()} elif (isinstance(data, Iterable) and not isinstance(data, str) and not isinstance(data, bytes)): if data: return unique(type(data)([get_structure(item) for item in data])) return StrType(data) if __name__ == "__main__": from pprint import pprint from datetime import datetime class MaClasse: pass nested = {'some types': {'MaClasse': MaClasse(), 'datetime': datetime.now(), 'empty-list': [], 'empty-tuple': (), 'float': 3.14, 'int': 0, 'list': [False,], 'set': {'a',}, 'str': 'Babylone', 'tuple': ('jah',)}, 'sequence types': {'lists': ['a', 'b', 'c', datetime.now(), [1, 2, 3], [1, 2, 3]], 'tuples': ('a', 'b', 'c', datetime.now(), [1, 2, 3], [1, 2, 3]), 'sets': {'hello', 'world', 42, True}}, '2 same dict 1 other': [{'same':3, 'as':b'the other'}, {'same':3, 'as':b'the other'}, {'different':'from','the':'other'}], 'play me': MaClasse} structure = get_structure(nested) print("The nested data:") pprint(nested) print("") print("Its mapping:") pprint(structure)