json中数据不规范,有时我们需要将数值(字符串类型的数值)统一保留多少位小数。
以下是我的代码,使用递归算法遍历json中所有的层。只要发现value值为浮点型或可转换成数值型的字符串则全部转换成浮点数;
具体代码如下:
class RoundJSON(object):
#data:需要处理的目标json,digit为保留多少位小数位默认保留4位
def round_data(self,data={},digit=4):#将data中的所有字段只要是数值则四舍五入
if(type(data)==type({})):
keys=data.keys()
if (len(keys) > 0 and type(keys)!=type(None)):
for key in keys:
value=data.get(key)
isnum=self.is_number(value)
if(isnum==True):
value = self.roundUp(value, digit)
data[key] = value
elif(type(value)==type({}) or type(value)==type([])):
self.round_data(value, digit)
elif(type(data)==type([])):
for i in range(len(data)):
if (type(data[i]) == type({})):
keys = data[i].keys()
if(len(keys)>0 and type(keys)!=type(None)):
for key in keys:
value = data[i].get(key)
if (self.is_number(value) == True):
value = self.roundUp(value, digit)
data[i][key] = value
elif(type(value)==type({}) or type(value)==type([])):
self.round_data(value, digit)
elif(type(data[i]) == type([]) and len(data[i])>0):
for value in data[i]:
if (self.is_number(value) == True):
value_new = self.roundUp(value, digit)
data[i]=[value_new if x==value else x for x in data[i]]
elif (type(value) == type({}) or type(value) == type([])):
self.round_data(value, digit)
else:
if (self.is_number(data[i]) == True):
value_new = self.roundUp(data[i], digit)
data=[value_new if x==data[i] else x for x in data]
elif (type(data[i]) == type({}) or type(data[i]) == type([])):
self.round_data(data[i], digit)
return data
def is_number(self,s): #判断字符串s是否是数值
try:
float(s)
return True
except Exception as e:
pass
try:
unicodedata.numeric(s)
return True
except Exception as e:
pass
return False
def roundUp(self, value, digit):
flag = self.is_number(value)
if (flag == True and 'e' not in str(value)): #排除科学计数法
result = str(value)
if (float(value) < 0):
result = result[1:]
if (result != ''):
indexDec = result.find('.')
if (indexDec > 0):
decimal = result[indexDec + 1:]
decimalCount = len(decimal)
if (decimalCount > digit):
xiaoshu = result[indexDec + digit + 1] # 第digit+1位小数
if (int(xiaoshu) > 4):
result = str(float(value) * -1 + pow(10, digit * -1))
# 存在进位的可能,小数点会移位
indexDec = result.find('.')
result = result[:indexDec + digit + 1]
else:
result = result[:indexDec + digit + 1]
else:
lens = digit - len(result[indexDec:]) + 1
for i in range(lens):
result += '0'
result = float(result) * -1
return result