我正在进行api调用并在json中收到回复,如此
result = {'foo': '123.456', 'bar': '23', 'donald': 'trump', 'time': '2016-04-07T05:31:49.532124Z'}
虽然结果是字典或列表,但内容始终是字符串。我想将这些值转换为适当的类型。 (即'123.456'
到浮点数,'23'
到int,'time'
到日期时间。)
我的代码有效,但似乎应该有更简单/更有效的方法来执行此操作。在那儿?
这是我的版本
from dateutil.parser import parse
def is_float(x):
try:
float(x)
return True
except ValueError:
return False
def is_int(x):
try:
a = float(x)
b = int(a)
except ValueError:
return False
else:
return a == b
def is_datetime(x):
try:
parse(x)
return True
except ValueError:
return False
def smartcast(x):
if isinstance(x, dict):
return { k:smartcast(v) for k, v in x.items() }
elif isinstance(x, list):
return map(smartcast, x)
elif is_int(x):
return int(x)
elif is_float(x):
return float(x)
elif is_datetime(x):
return parse(x)
else:
return x
修改:如果可能,我希望避免使用try
和except
。我想将它实现为异步扭曲程序,我认为try
和except
阻塞,所以它只是使程序同步。我是新手,所以我不确定这是不是真的。
根据Francesco的解决方案,这是更新的代码。
from dateutil.parser import parse
def smartcast(x):
if isinstance(x, dict):
return { k:smartcast(v) for k, v in x.items() }
elif isinstance(x, list):
return map(smartcast, x)
else:
for t in [int, float, parse]:
try:
return t(x)
except ValueError:
continue
return x
答案 0 :(得分:3)
什么是合适的类型?我要求这一点强调有时候对于人类来说还不清楚类型是什么:你确定“42”总是一个int或有时它必须被视为一个字符串?
无论如何,正如您所做的那样,您可以使用在您的环境中有意义的规则来构建解决方案。
在您的情况下,您可以通过简单的循环简化代码
from dateutil.parser import parse
tests = [int, float, parse]
def smartcast(value):
for test in tests:
try:
return test(value)
except ValueError:
continue
# No match
return value
答案 1 :(得分:0)
使用ast.literal_eval()怎么样?
https://docs.python.org/2/library/ast.html#ast.literal_eval
投票支持弗朗西斯科的回答。你需要提出异常。