If I understand correctly, here's my idea:
>>> a
array([[False, True, True, True],
[ True, True, True, True],
[ True, True, True, True]])
>>> sub
>>> array([ True, True, True, True])
>>>
>>> result, = np.where(np.all(a == sub, axis=1))
>>> result
array([1, 2])
Details regarding this solution:
a == sub gives you
>>> a == sub
array([[False, True, True, True],
[ True, True, True, True],
[ True, True, True, True]])
a boolean array where for each row the True/False value indicates if the value in a is equal to the corresponding value in sub. (sub is being broadcasted along the rows here.)
np.all(a == sub, axis=1) gives you
>>> np.all(a == sub, axis=1)
array([False, True, True])
a boolean array corresponding to the rows of a that are equal to sub.
Using np.where on this sub-result gives you the indices where this boolean array is True.
Details regarding your attempt:
np.where(a == sub) (the tolist is unnecessary) gives you two arrays which together indicate the indices where the array a == sub is True.
>>> np.where(a == sub)
(array([0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2]),
array([1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3]))
If you would zip these two arrays together you would get the row/column indices where a == sub is True, i.e.
>>> for row, col in zip(*np.where(a==sub)):
...: print('a == sub is True at ({}, {})'.format(row, col))
a == sub is True at (0, 1)
a == sub is True at (0, 2)
a == sub is True at (0, 3)
a == sub is True at (1, 0)
a == sub is True at (1, 1)
a == sub is True at (1, 2)
a == sub is True at (1, 3)
a == sub is True at (2, 0)
a == sub is True at (2, 1)
a == sub is True at (2, 2)
a == sub is True at (2, 3)
[0 0 0 1 1 1 1 2 2 2 2], not[].ais also incorrect, bacause it's meant to be a shaped np array