Convert python decimal to string in deeply nested and unpredictable list

后端 未结 2 537
悲&欢浪女
悲&欢浪女 2020-12-06 22:52

I am trying to loop through every value in a deeply nested/mixed list and convert any Decimal instances to string so that I can store them in mongo.

My attempt at re

2条回答
  •  鱼传尺愫
    2020-12-06 23:24

    To convert Decimal during json.dump() using default parameter:

    import json
    import sys
    from decimal import Decimal
    
    def default(obj):
        if isinstance(obj, Decimal):
            return str(obj)
        else:
            raise TypeError(obj)
    
    # convert during dump
    json.dump(data, sys.stdout, indent=2, default=default)
    

    To modify data inplace:

    import json
    import sys
    from collections import MutableMapping, MutableSequence
    from decimal import Decimal
    
    def convert_decimal(json_data):
        stack = [json_data]
        while stack:
            json_data = stack.pop()
            if isinstance(json_data, MutableMapping): # json object
                it = json_data.items()
            elif isinstance(json_data, MutableSequence): # json array
                it = enumerate(json_data)
            else: # scalar data
                continue
    
            for k, v in it:
                if isinstance(v, Decimal):
                    json_data[k] = str(v)
                else:
                    stack.append(v)
    
    
    # convert inplace
    convert_decimal(data)
    json.dump(data, sys.stdout, indent=2)
    

    Both scripts produce the same output:

    [
      {
        "Payments": {
          "OtherFees": "0", 
          "APR": "2.54", 
          "Rate": "0.0254", 
          "IsCapped": true, 
          "Name": "TestData", 
          "Program": {
            "Description": null, 
            "ProgramName": "AST"
          }, 
          "AppliedIds": [], 
          "CapCostTotal": "27900", 
          "Tax": "0", 
          "Payment": "495.64"
        }
      }
    ]
    

    You could simplify convert_decimal() if you use a generic get_items() function:

    def convert_decimal(json_data):
        stack = [json_data]
        while stack:
            json_data = stack.pop()
            for k, v in get_items(json_data):
                if isinstance(v, Decimal):
                    json_data[k] = str(v)
                else:
                    stack.append(v)
    

提交回复
热议问题