0

I'm using the following function to create a clone of a dictionary (which can be of arbitrary depth and structure) with decimals converted to floats. This will be used to deal with JSON returned from DynamoDB, but for fun I decided to make it as general-purpose as possible:

def all_decs_to_float(my_input):
    """Take an input and return a duplicate with all decs converted to floats."""

    if isinstance(my_input, decimal.Decimal):
        return float(my_input)
    elif isinstance(my_input, dict):
        return {k: all_decs_to_float(v) for k, v in my_input.items()}
    elif isinstance(my_input, list):
        return [all_decs_to_float(v) for v in my_input]
    elif isinstance(my_input, set):
        return {all_decs_to_float(v) for v in my_input}
    elif isinstance(my_input, tuple):
        # Tuple function is used here to avoid returning a generator item.
        return tuple(all_decs_to_float(v) for v in my_input)
    else:
        return my_input

input/output:

>>> my_test_dict
{'item1': 'test', 'item2': {'item3': 2.0, 'item4': {'item5': Decimal('3')}, 'l': [1, 2, '3', Decimal('4'), 5], 's': {1, 2, Decimal('4'), 5, '3'}, 't': (1, 2, '3', Decimal('4'), 5)}}

>>> all_decs_to_float(my_test_dict)
{'item1': 'test', 'item2': {'item3': 2.0, 'item4': {'item5': 3.0}, 'l': [1, 2, '3', 4.0, 5], 's': {1, 2, 4.0, 5, '3'}, 't': (1, 2, '3', 4.0, 5)}}

I want to avoid modifying the original object (I think it's more "pythonic" - but please correct me if I'm wrong) which is why I'm not updating the values in place like the solution given here. I'm looking for something elegant because I don't like the idea of a long series of elif cases and would prefer something more generalised - I'm definitely an amateur so there are bound to be some types that I've never heard of.

I'm aware of collections.abc.Collection but I'm not sure how I'd use that to return a duplicate of the object (as opposed to just testing whether it's a member of this collection).

Gethin LW
  • 21
  • 2

0 Answers0