繁体   English   中英

从文件中每4个字节读取3个字节数组

[英]Read 3 of every 4 bytes from file into bytearray

我是python的新手。 我目前正在将文件内容读入字节数组,如下所示:

self.palette = bytearray(fp.read(paletteSize*4))

除了读取所有数据,我还需要执行以下操作:

palette[0] = fp.read(1)
palette[1] = fp.read(1)
palette[2] = fp.read(1)
fp.read(1) #throw a byte away
palette[3] = fp.read(1)
# etc thru paletteSize * 4 bytes, resulting in a size * 3 array

基本上,我需要丢弃每个第4个字节,并将其余字节打包到大小为3/4的数组中。

在代码中性能最佳和最干净的最佳方法是什么? 我知道我可以像上面那样在范围上进行for循环手动进行此操作,但这看起来确实很丑,并且在python中而不是在本机C代码中涉及大量内存副本。

我问的原因:这是micropython,文件可能会很大(4+ KB),因此节省25%的意义重大。

剧透警报:我正在读取位图文件的调色板部分,该文件编码为蓝色,绿色,红色,0x00的四个字节元组-每个调色板条目的第4个字节都是无用的数据。

由于已经具有调色板大小,因此可以为它预先分配内存,以在向其添加数据时扩展字节数组来节省一些开销。 使用循环一次读取3个字节,并执行搜索以跳过1个字节:

palette = bytearray(paletteSize * 3)
for i in range(paletteSize):
    palette[i * 3: (i + 1) * 3] = fp.read(3)
    fp.seek(1, 1)

因此,今天我了解了Python中的切片分配,这是缺少的魔术。 谢谢@blhsing :)

我最终得到了这个版本,该版本避免了循环切片分配中的某些数学运算:

self.palette = bytearray(paletteSize * 3)
   for i in range(0, paletteSize*3, 3):
      self.palette[i : (i + 3)] = fp.read(3)
      fp.seek(1, 1)

添加为答案而不是注释,因为stackoverflow注释格式很烂

使用struct模块。

s = struct.Struct("BBB")
b = bytearray()
for i in range(paletteSize)
    b.extend(s.unpack_from(f.read(4)))  # b.extend(f.read(4)[:3]) would also work

您甚至可以将其简化为

s = struct.Struct("BBBx" * paletteSize)
b = bytearray(s.unpack(f.read(paletteSize*4)))

尽管我还没有测试过 我从未使用过像这样大的格式字符串,但从理论上讲,它应该可以工作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM