来自生成器的 Python 字节对象

标签 python arrays python-3.x generator

假设我有一个像

gen = (i*2 for i in range(100))

我现在想创建一个包含生成器产生的所有值的字节对象。我可以执行以下操作:
b = bytes(gen)

我现在的问题是:自从 bytes对象是不可变的,在这种情况下内存分配是如何工作的?我是否必须假设对于生成器产生的每个元素,都有一个新的 bytes创建的对象,将先前的内容加上另一个元素复制到其中?这将是非常低效的,尤其是对于更大长度的发电机。而且由于生成器不提供任何长度信息,似乎没有任何其他方法可以在内部预先分配所需的内存。

再说一次,用尽可能少的内存使用来实现这一目标的更好方法是什么?如果我使用(可变)bytearray首先并将其转换为 bytes目的?
b = bytes(bytearray(gen))

甚至是一个 list ?
b = bytes(list(gen))

但这看起来有点奇怪和违反直觉......

背景:我已经通过来自另一个模块(.pyd)的 C-API 一次读取一个字节(作为 0..255 中的 Python 整数)的特定生成器,并且序列的总长度事先已经知道,最多到 2**25 字节。我的读出函数应该收集这些并返回 bytes对象,我认为这是合适的,因为数据是只读的。

最佳答案

bytes(iterator)使用内部 C-API _PyBytes_FromIterator 从迭代器创建字节对象函数,使用特殊 _PyBytes_Writer协议(protocol)。它在内部使用一个缓冲区,当它溢出时使用规则调整大小:

bufsize += bufsize  / OVERALLOCATE_FACTOR
对于 linux OVERALLOCATE_FACTOR=4,对于 windows OVERALLOCATE_FACTOR=2。
那些。这个过程看起来就像写入 RAM 中的文件。最后,缓冲区的内容返回。

关于来自生成器的 Python 字节对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46318527/

相关文章:

python - 在Python 3中动态导入模块时出现问题

python - Django 如何从 ManyToManyField 序列化并列出所有

arrays - Swift 3 中数组平衡点的公共(public)函数

python - 删除 pandas 数据框中的重复项后替换特定列值

python - 如何从 2 个值形成一个字符串

arrays - 如何使用jq根据内部数组中的值过滤对象数组?

C : Making sure the element you return from an array is correct

python - 如何修复 Python pip install openai 错误 : subprocess-exited-with-error

python - 如何迭代不同列表的乘积?

python - 如何将我的数据导入到 python 中