def transpose(m):
    """transpose(m): transposes a 2D matrix, made of tuples or lists of tuples or lists,
    keeping their type.

    >>> transpose([])
    Traceback (most recent call last):
      ...
    IndexError: list index out of range
    >>> transpose([[]])
    []
    >>> transpose([1,2,3])
    Traceback (most recent call last):
      ...
    TypeError: zip argument #1 must support iteration
    >>> transpose([[1,2,3]])
    [[1], [2], [3]]
    >>> transpose( [[2, 2, 2], [2, 2, 2]] )
    [[2, 2], [2, 2], [2, 2]]
    >>> transpose( [(2, 2, 2), (2, 2, 2)] )
    [(2, 2), (2, 2), (2, 2)]
    >>> transpose( ([2, 2, 2], [2, 2, 2]) )
    ([2, 2], [2, 2], [2, 2])
    >>> transpose( ((2, 2, 2), (2, 2, 2)) )
    ((2, 2), (2, 2), (2, 2))
    >>> t = [[[1], [2]], [[3], [4]], [[5], [6]]]
    >>> transpose(t)
    [[[1], [3], [5]], [[2], [4], [6]]]
    """
    if isinstance(m, list):
        if isinstance(m[0], list):
            return map(list, zip(*m))
        else:
            return zip(*m) # faster
    else:
        if isinstance(m[0], list):
            return tuple(map(list, zip(*m)))
        else:
            return tuple( zip(*m) )
transpose(m): transposes a 2D matrix, made of tuples or lists of tuples or lists,
    keeping their type.

    >>> transpose([])
    Traceback (most recent call last):
      ...
    IndexError: list index out of range
    >>> transpose([[]])
    []
    >>> transpose([1,2,3])
    Traceback (most recent call last):
      ...
    TypeError: zip argument #1 must support iteration
    >>> transpose([[1,2,3]])
    [[1], [2], [3]]
    >>> transpose( [[2, 2, 2], [2, 2, 2]] )
    [[2, 2], [2, 2], [2, 2]]
    >>> transpose( [(2, 2, 2), (2, 2, 2)] )
    [(2, 2), (2, 2), (2, 2)]
    >>> transpose( ([2, 2, 2], [2, 2, 2]) )
    ([2, 2], [2, 2], [2, 2])
    >>> transpose( ((2, 2, 2), (2, 2, 2)) )
    ((2, 2), (2, 2), (2, 2))
    >>> t = [[[1], [2]], [[3], [4]], [[5], [6]]]
    >>> transpose(t)
    [[[1], [3], [5]], [[2], [4], [6]]]
    
recipes/Python/498123_tensor_and_transpose/recipe-498123.py