Python 3.4以降では、新しい関数を使用できますstruct.iter_unpack
。
struct.iter_unpack(fmt, buffer)
フォーマット文字列fmtに従って、バッファバッファから繰り返し解凍します。この関数は、すべてのコンテンツが消費されるまで、バッファーから同じサイズのチャンクを読み取るイテレーターを返します。バイト単位のバッファのサイズは、calcsize()に反映されているように、フォーマットに必要なサイズの倍数である必要があります。
各反復は、フォーマット文字列で指定されたタプルを生成します。
b'\x01\x02\x03'*3
繰り返しフォーマット文字列'<2sc'
(2文字の後に1文字が続く、完了するまで繰り返す)を使用して配列を解凍するとします。
を使用iter_unpack
すると、次のことができます。
>>> import struct
>>> some_bytes = b'\x01\x02\x03'*3
>>> fmt = '<2sc'
>>>
>>> tuple(struct.iter_unpack(fmt, some_bytes))
((b'\x01\x02', b'\x03'), (b'\x01\x02', b'\x03'), (b'\x01\x02', b'\x03'))
この結果のネストを解除する場合は、を使用して行うことができますitertools.chain.from_iterable
。
>>> from itertools import chain
>>> tuple(chain.from_iterable(struct.iter_unpack(fmt, some_bytes)))
(b'\x01\x02', b'\x03', b'\x01\x02', b'\x03', b'\x01\x02', b'\x03')
もちろん、ネストされた内包表記を使用して同じことを行うこともできます。
>>> tuple(x for subtuple in struct.iter_unpack(fmt, some_bytes) for x in subtuple)
(b'\x01\x02', b'\x03', b'\x01\x02', b'\x03', b'\x01\x02', b'\x03')