Arbitrary tensor contraction.

This PR adds support for contraction along arbitrary dimensions of a qobj, whether those dimensions are state, operator or superoperator indices. The generalization is provided by a small number of utility functions for manipulation ``dims`` properties with few assumptions. Unfortunately, due to the limitations of ``scipy.sparse``, this functionality is implemented on dense arrays, but for small matrices, it works suitably fast.
This is just a small thing, but tensor accepts a list as argument as well as multiple arguments, but since a list is ok there is no need to distribute the list into separate arguments using `(*[...])`.