docs: def qtable(columns, data, **meta):
      '''Creates a QTable out of given column names and data, and initialises the 
      meta data.
      
      :class:`.QTable` is represented internally by `numpy.core.records.recarray`.
      Data for each column is converted to :class:`.QList` via :func:`.qlist` 
      function. If qtype indicator is defined for a column, this information
      is used for explicit array conversion.
      
      Table examples:
    
        >>> # q: flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
        >>> t = qtable(qlist(numpy.array(['name', 'iq']), qtype = QSYMBOL_LIST), 
        ...     [qlist(numpy.array(['Dent', 'Beeblebrox', 'Prefect'])), 
        ...      qlist(numpy.array([98, 42, 126], dtype=numpy.int64))])
        >>> print('%s dtype: %s meta: %s: %s' % (type(t), t.dtype, t.meta, t))
        <class 'qpython.qcollection.QTable'> dtype: [('name', 'S10'), ('iq', '<i8')] meta: metadata(iq=-7, qtype=98, name=-11): [('Dent', 98L) ('Beeblebrox', 42L) ('Prefect', 126L)]
        
        >>> # q: flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
        >>> t = qtable(qlist(numpy.array(['name', 'iq']), qtype = QSYMBOL_LIST),
        ...           [qlist(['Dent', 'Beeblebrox', 'Prefect'], qtype = QSYMBOL_LIST), 
        ...            qlist([98, 42, 126], qtype = QLONG_LIST)])
        >>> print('%s dtype: %s meta: %s: %s' % (type(t), t.dtype, t.meta, t))
        <class 'qpython.qcollection.QTable'> dtype: [('name', 'S10'), ('iq', '<i8')] meta: metadata(iq=-7, qtype=98, name=-11): [('Dent', 98L) ('Beeblebrox', 42L) ('Prefect', 126L)]
        
        >>> # q: flip `name`iq!(`Dent`Beeblebrox`Prefect;98 42 126)
        >>> t = qtable(['name', 'iq'],
        ...            [['Dent', 'Beeblebrox', 'Prefect'], 
        ...             [98, 42, 126]],
        ...            name = QSYMBOL, iq = QLONG)
        >>> print('%s dtype: %s meta: %s: %s' % (type(t), t.dtype, t.meta, t)) 
        <class 'qpython.qcollection.QTable'> dtype: [('name', 'S10'), ('iq', '<i8')] meta: metadata(iq=-7, qtype=98, name=-11): [('Dent', 98L) ('Beeblebrox', 42L) ('Prefect', 126L)]
        
        >>> # q: flip `name`iq`fullname!(`Dent`Beeblebrox`Prefect;98 42 126;("Arthur Dent"; "Zaphod Beeblebrox"; "Ford Prefect"))
        >>> t = qtable(('name', 'iq', 'fullname'),
        ...            [qlist(numpy.array(['Dent', 'Beeblebrox', 'Prefect']), qtype = QSYMBOL_LIST), 
        ...             qlist(numpy.array([98, 42, 126]), qtype = QLONG_LIST),
        ...             qlist(numpy.array(["Arthur Dent", "Zaphod Beeblebrox", "Ford Prefect"]), qtype = QSTRING_LIST)])
        <class 'qpython.qcollection.QTable'> dtype: [('name', 'S10'), ('iq', '<i8'), ('fullname', 'O')] meta: metadata(iq=-7, fullname=0, qtype=98, name=-11): [('Dent', 98L, 'Arthur Dent') ('Beeblebrox', 42L, 'Zaphod Beeblebrox') ('Prefect', 126L, 'Ford Prefect')]
      
      :Parameters:
       - `columns` (list of `strings`) - table column names 
       - `data` (list of lists) - list of columns containing table data
      
      :Kwargs:
       - `meta` (`integer`) - qtype for particular column 
      
      :returns: `QTable` - representation of q table
      
      :raises: `ValueError`
      '''
      if len(columns) != len(data):
          raise ValueError('Number of columns doesn`t match the data layout. %s vs %s' % (len(columns), len(data)))
  
      meta = {} if not meta else meta
  
      if not 'qtype' in meta:
          meta['qtype'] = QTABLE
  
      dtypes = []
      for i in range(len(columns)):
          column_name = columns[i] if isinstance(columns[i], str) else columns[i].decode("utf-8")
          
          if isinstance(data[i], str):
              # convert character list (represented as string) to numpy representation
              data[i] = numpy.array(list(data[i]), dtype = numpy.string_)
          if isinstance(data[i], bytes):
              data[i] = numpy.array(list(data[i].decode()), dtype = numpy.string_)
  
          if column_name in meta:
              data[i] = qlist(data[i], qtype = meta[column_name])
          elif not isinstance(data[i], QList):
              if type(data[i]) in (list, tuple):
                  data[i] = qlist(data[i], qtype = QGENERAL_LIST)
              else:
                  data[i] = qlist(data[i])
  
          
          meta[column_name] = data[i].meta.qtype
          dtypes.append((column_name, data[i].dtype))
  
      table = numpy.core.records.fromarrays(data, dtype = dtypes)
      table = table.view(QTable)
  
      table._meta_init(**meta)
      return table