我有一个 python 2.7 字典,例如 {u"eat": u"糖果", u"drink": u"café"}
,我需要使用 JSON 传输它。 JSON 字符串必须是常规 ASCII,并且必须少于 256 个字符。
到目前为止,我已经编写了以下代码:
import json
def payload_to_json(payload, max_size = 256):
while True:
json_string = json.dumps(payload, separators = (',', ':'))
if len(json_string) <= max_size:
return json_string
max_length, found_key = 0, None
for key, value in payload.iteritems():
length = len(value)
if length > max_length:
max_length = length
found_key = key
if max_length == 0:
return "" # just in case max_size is really low
payload[found_key] = payload[found_key][:-1] # remove one char
它按预期工作:
>>> payload = {u"eat": u"糖果", u"drink": u"café"}
>>> print payload_to_json(payload)
{"drink":"caf\u00e9","eat":"\u7cd6\u679c"}
>>> print payload_to_json(payload, max_size=41)
{"drink":"caf","eat":"\u7cd6\u679c"}
>>> print payload_to_json(payload, max_size=35)
{"drink":"ca","eat":"\u7cd6\u679c"}
>>> print payload_to_json(payload, max_size=34)
{"drink":"c","eat":"\u7cd6\u679c"}
>>> print payload_to_json(payload, max_size=30)
{"drink":"c","eat":"\u7cd6"}
>>> print payload_to_json(payload, max_size=21)
{"drink":"","eat":""}
>>> print payload_to_json(payload, max_size=20)
我觉得应该有办法优化这个!我真的一次剥离一个字符,感觉很不对。
我的问题非常接近 this one ,除了我使用 python 2.7,只要源字符串包含非 ASCII unicode 字符,json 编码器就会生成相当长的 JSON 字符串。
另外,我很确定这会破坏 UTF-16 代理对...
最佳答案
如果你试图让它更快(你不应该这样做,除非你知道这是你程序中的一个热点,并且有实际的性能成本),你可以先猜测要剥离的字符数,然后处理剩菜。
首先,如果你需要剥离 52 个字符,并且有 10 个键,你需要从 2 个键中每个剥离 6 个字符,从其他 8 个键中每个剥离 5 个字符,对吗?当然,除了您可能试图从只有 4 个字符长的内容中删除 6 个字符,这意味着您最终仍会超出限制 2 个字符。但是您可以跟踪这些剩菜并在完成后处理它们。不太可能有足够的剩菜来让另一次通过“快速”版本值得做,所以你最好使用“慢速”版本。
def payload_to_json(payload, max_size = 256):
json_string = json.dumps(payload, separators = (',', ':'))
chars_to_strip = len(json_string) - max_size
if chars_to_strip <= 0:
return json_string
key_count = len(payload)
chars_per_key, extras = divmod(chars_to_strip, key_count)
leftover = 0
for i, key in enumerate(payload):
to_strip = chars_per_key + (i < extras)
orig_len = len(payload[key])
if orig_len < to_strip:
payload[key] = ''
leftover += to_strip - orig_len
else:
payload[key] = payload[key][:-to_strip]
if leftover:
return slow_payload_to_json(payload, max_size)
else:
return json.dumps(payload, separators = (',', ':'))
我不确定这实际上会在您的用例中加快速度。对于非常小的物体和最大尺寸,如果它真的减慢了速度,我不会感到惊讶。但是对于超过最大尺寸的巨大物体,它可能会有很大帮助。
关于python - 如何截断字典中的数据以使生成的 JSON 不超过 n 个字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15168974/