A list comprehension does the job nicely:
In [191]: a = np.array([np.array([1.]), np.array([2, 3]), np.array(['a', 'b', 'c'])])
In [192]: a
Out[192]:
array([array([ 1.]), array([2, 3]),
array(['a', 'b', 'c'],
dtype='<U1')], dtype=object)
In [193]: [tuple(i) for i in a]
Out[193]: [(1.0,), (2, 3), ('a', 'b', 'c')]
In [194]: tuple([tuple(i) for i in a])
Out[194]: ((1.0,), (2, 3), ('a', 'b', 'c))
Wrapping the list of arrays in another array layer doesn't do much. An array of dtype object is just a list with a ndarray wrapper. Most operations of a will treat it like a list.
In [195]: ll=[np.array([1.]), np.array([2, 3]), np.array(['a', 'b', 'c'])]In [196]: ll
Out[196]:
[array([ 1.]), array([2, 3]), array(['a', 'b', 'c'],
dtype='<U1')]
In [197]: [tuple(l) for l in ll]
Out[197]: [(1.0,), (2, 3), ('a', 'b', 'c')]
correction - we need to use tolist() first if we want to convert the elements of the inner arrays. tuple(i) is like list(i), iterating on the 1st dimension, while i.tolist() does a recursive conversion.
In [204]: type([tuple(i.tolist()) for i in a][0][0])
Out[204]: float
More on the difference between list and tolist when we apply them to a 2d array:
In [210]: np.ones((2,3)).tolist()
Out[210]: [[1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]
In [211]: list(np.ones((2,3)))
Out[211]: [array([ 1., 1., 1.]), array([ 1., 1., 1.])]
In [212]: tuple(np.ones((2,3)))
Out[212]: (array([ 1., 1., 1.]), array([ 1., 1., 1.]))
There isn't a totuple() method, and nothing quick and easy that would convert a nested lists of lists to a nested tuple of tuples.
tolist does not recurse through the dtype=object layer:
In [214]: a.tolist()
Out[214]:
[array([ 1.]), array([2, 3]), array(['a', 'b', 'c'],
dtype='<U1')]