title: Python: What's the best way to unpack a struct array from binary data
body: <p>I'm parsing a binary file format (OpenType font file). The format is a complex tree of many different struct types, but one recurring pattern is to have an array of records of a particular format. I've written code using <code>struct.unpack</code> to get one record at a time. But I'm wondering if there's a way I'm missing to parse the entire array of records?</p>
  
  <p>The following is an example of unpacked results for one particular kind of record array:</p>
  
  <pre><code>[{'glyphID': 288, 'paletteIndex': 0}, {'glyphID': 289, 'paletteIndex': 1}, {'glyphID': 518, 'paletteIndex': 0}, ...]    list
  </code></pre>
  
  <p>This is what I'm doing at present: I've created a generic function to unpack an arbitrary records array (consistent record format in any given call).</p>
  
  <pre class="lang-py prettyprint-override"><code>def tryReadRecordsArrayFromBuffer(buffer, numRecords, format, fieldNames):
      recordLength = struct.calcsize(format)
      array = []
      index = 0
      for i in range(numRecords):
          record = {}
          vals = struct.unpack(format, buffer[index : index + recordLength])
          for k, v in zip(fieldNames, vals):
              record[k] = v
          array.append(record)
          index += recordLength
  
      return array
  </code></pre>
  
  <p>The <code>buffer</code> parameter is a byte sequence at least the size of the array, with the first record to be unpacked at the start of the sequence.</p>
  
  <p>The <code>format</code> parameter is a <code>struct</code> format string, according to the type of record array being read. In one case, the format string might be <code>"&gt;3H"</code>; in another case, it might be <code>"&gt;4s2H"</code>; etc. For the above example of results, it was <code>"&gt;2H"</code>.</p>
  
  <p>The <code>fieldNames</code> parameter is a sequence of strings for the field names in the given record type. For the above example of results, this was <code>("glyphID", "paletteIndex")</code>.</p>
  
  <p>So, I'm stepping through the buffer (byte sequence data), getting sequential slices and unpacking the records one at a time, creating a dict for each record and appending them to the <code>array</code> list.</p>
  
  <p>Is there a better way to do this, a method like <code>unpack</code> in some module that allows defining a format as an array of structs and unpacking the whole shebang at once?</p>