90 lines
3 KiB
Python
90 lines
3 KiB
Python
|
|
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)
|