I simplified @plaes answer (see below). Still recursive but easier to read and handles top-level lists/dicts, as well as mixed dict/list/suds combinations.
def pycast(o):
if hasattr(o, '__keylist__'):
return {k:pycast(v) for k,v in asdict(o).items()}
elif isinstance(o, dict):
return {k:pycast(v) for k,v in o.items()}
elif isinstance(o, list):
return [pycast(x) for x in o]
else:
return o