我在Python中有一个列表,该列表由具有以下格式的元组组成:(整数,浮点数)。我想将此列表写入io字节或io原始流,而不必将int和/或float转换为字符串。我怎样才能做到这一点?谢谢。
答案 0 :(得分:1)
有许多格式可用于将Python对象序列化为字节。每个都有优点和缺点。
如果数据仅包含整数和浮点元组的列表,则使工作相当简单。
我们假设,这是数据:
data = 100 * [(1, 1.111), (18, 1.234), (555555, 0.001), (-1, 1e70)]
我不清楚其中哪些属于“字符串”类别。最明显的“字符串”格式为str(data)
。它有多大?
>>> len(str(data))
5500
这占用5500个字节。这个问题要求进一步压缩。因此,我们正在寻找比5500字节短得多的东西。
JSON 是一种非常流行的格式(它也是一个字符串)。它有多大?
>>> len(json.dumps(data))
5500
它具有相同的大小(5500字节),但至少定义明确。可以更小吗? Bzip JSON 怎么样?
>>> len(bz2.compress(json.dumps(data).encode('utf-8')))
131
那好多了!
由于重复的模式,这可能非常好。是否有不使用压缩的格式?也许是腌?
>>> len(pickle.dumps(data))
862
不如zip(当然!),但仍然很好。
我们可以做个腌制咸菜吗?
>>> len(bz2.compress(pickle.dumps(data)))
155
更好,但是没有理由比BZipped JSON更好。
其他格式如何?您可以使用struct模块将每个元组转换为此C 结构的等价物:
struct {
int i;
double f;
};
但是,那么您必须知道int可以有多大。 Python int可以随心所欲,但如果您愿意,例如知道所有数字都在0到255之间,您只需要一个字节。对于浮点数,您需要64位(即8个字节),否则将失去精度。因此,这将达到约1000个字节。不太好。
Python's documentation on Persistence中还记录了其他内置选项。
您也可以发明自己的格式。
最后,您必须决定最适合您的情况。
答案 1 :(得分:0)
使用struct module可以非常容易地直接转储整数并将其浮动为字节。
>>> import struct
>>> data = [(2, 1.0), (3, 2.0), (25, 55.5)]
>>> for tup in data:
bytes_data = struct.pack("<ld", *tup)
print(bytes_data)
b'\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\xf0?'
b'\x03\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00@'
b'\x19\x00\x00\x00\x00\x00\x00\x00\x00\xc0K@'
顺便说一句,我用作pack
函数的第一个参数的字符串是一种格式标识符,它告诉您每个数字的类型和大小,在这种情况下,l
是一个长符号整数,d
是浮点双精度。