在我的Python应用程序中,我想找到一种在文件中对无符号整数序列进行空间高效编码的方法,小整数非常常见,而大整数相对不常见。我知道我需要的是某种形式的variable-length quantity encoding(VLQ)
我有一个(可能有缺陷和/或可能是特定于CPython的)内存来读取Python在内部使用VLQ策略来表示int
的某个地方。这些编码/解码例程是否可以从Python访问?和/或在Python中是否有另一种快速执行VLQ的方法
我调查过的可能性:
struct
模块文档中没有看到任何相关内容李>python VLQ
或python "group varint"
的网络搜索中得到任何有意义的点击李>encode = lambda n: chr(n).encode('utf-8')
和decode = lambda x: ord(x.decode('utf-8'))
,但不幸的是encode(n)
在55296 <= n <= 57343
时引发了一个带有消息“代理不允许”的UnicodeEncodeError
李>更新:@don'ttalkjustcode正确地将pickle
模块标识为Python标准库执行类似于这样的操作的地方,特别是在pickle.encode_long()
和pickle.decode_long()
中。它们是纯Python实现,在Python 2.7中,它们围绕一个名为pickle._binascii
的二进制子模块,但在Python 3.2+中,工作似乎是通过int
类的内置方法完成的,从而导致:
encode = lambda n: n.to_bytes(n.bit_length()//8 + 1, 'little', signed=False)
decode = lambda x: int.from_bytes(x, 'little', signed=False)
然而,我猜这些是不完整的(或者,对于小整数,效率低下)可变长度编码,因为您需要花费另一个字节来单独编码编码的长度
我真正需要的是类似LEB128编码的东西,对于它pure-Python solutions exist,但是现在我看到了int.to_bytes()
和int.from_bytes()
,我猜Python并不是本机实现的
是的,
pickle
做了类似的事情。在我看来,这很体面。例如,一百万个随机大小为1到16字节的随机整数被编码到~10.75 MB。然后lzma.compress
将其降低到~10MB。与8.5MB的“原始数据大小”(100万个整数平均每个8.5字节)相比,情况还不错。LEB128还占用约10 MB的空间,非常小输出:
Try it online!
相关问题 更多 >
编程相关推荐