将元组列表(int,float)写入流而无需转换为字符串

时间:2019-03-05 20:40:08

标签: python list io byte

我在Python中有一个列表,该列表由具有以下格式的元组组成:(整数,浮点数)。我想将此列表写入io字节或io原始流,而不必将int和/或float转换为字符串。我怎样才能做到这一点?谢谢。

2 个答案:

答案 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是浮点双精度。