def hash_tuples(vals, encoding='<STR_LIT:utf8>', hash_key=None):
is_tuple = False<EOL>if isinstance(vals, tuple):<EOL><INDENT>vals = [vals]<EOL>is_tuple = True<EOL><DEDENT>elif not is_list_like(vals):<EOL><INDENT>raise TypeError("<STR_LIT>")<EOL><DEDENT>from pandas import Categorical, MultiIndex<EOL>if not isinstance(vals, ABCMultiIndex):<EOL><INDENT>vals = MultiIndex.from_tuples(vals)<EOL><DEDENT>vals = [Categorical(vals.codes[level],<EOL>vals.levels[level],<EOL>ordered=False,<EOL>fastpath=True)<EOL>for level in range(vals.nlevels)]<EOL>hashes = (_hash_categorical(cat,<EOL>encoding=encoding,<EOL>hash_key=hash_key)<EOL>for cat in vals)<EOL>h = _combine_hash_arrays(hashes, len(vals))<EOL>if is_tuple:<EOL><INDENT>h = h[<NUM_LIT:0>]<EOL><DEDENT>return h<EOL>
Hash an MultiIndex / list-of-tuples efficiently

.. versionadded:: 0.20.0

Parameters
----------
vals : MultiIndex, list-of-tuples, or single tuple
encoding : string, default 'utf8'
hash_key : string key to encode, default to _default_hash_key

Returns
-------
ndarray of hashed values array