Is there a difference between np.matrix(np.array([0,0])) and np.matrix([0,0])?
No, they're absolutely the same.

In this case there is absolutely no difference apart from perhaps a trivial amount of processing time.  This is all open source code so we can just read it:

The relevant part of numpy for us here is the matrix constructor (yes, np.matrix is a python class below the hood).  In a summary from the NumPy code we see:

class matrix(N.ndarray):
# ...
    def __new__(subtype, data, dtype=None, copy=True):
    # ...
        if isinstance(data, N.ndarray):
            if dtype is None:
                intype = data.dtype
            else:
                intype = N.dtype(dtype)
            new = data.view(subtype)
            if intype != data.dtype:
                return new.astype(intype)
            if copy: return new.copy()
            else: return new
        # ...
        arr = N.array(data, dtype=dtype, copy=copy)
        ndim = arr.ndim
        shape = arr.shape
        # some extra checks
        ret = N.ndarray.__new__(subtype, shape, arr.dtype,
                                buffer=arr,
                                order=order)
        return ret


What we give as the data argument is literally what we give to to np.matrix().  Therefore we can draw for the two cases:

np.matrix([0, 0])


The python interpreter builds two integers: 0 and 0.
The python interpreter builds a list from the pointers to the two integers.
The python interpreter evaluates the matrix constructor with the list as data.
The if in the constructor is not executed, instead an np.array is build from the list.
Inside the array constructor data types are checked.
The final array is returned (the second array constructor perform much less work because it is passed buffer=)


np.matrix(np.array([0, 0]))


The python interpreter builds two integers: 0 and 0.
The python interpreter builds a list from the pointers to the two integers.
The python interpreter evaluates the array constructor.
The resulting array is passed as data to the matrix constructor, and the if is executed.
Within the if the data type is taken from the existing array.
The array is copied an returned.




Both ways execute pretty much the same number of constructors and lines of code.  One could argue that copying the array (the copy= argument) may be a slow operation.  Yet, given the fact that to have enough data for array.copy() to be slow one would first need to construct a full python list of that size, the copy() time is negligible compared to the list construction.  In other words, both methods need to construct the list - because python will always evaluate arguments before passing them - which is the slowest part of the execution of this code.

As for the return value, they're absolutely and completely the same.  Most of the code within the constructor summarized (and linked) above is to make sure that you get the same return if you give equivalent input.



P.S. (Unrelated Note) If one starts reading data from a file (or any other external source) the picture changes.  If one reads directly into an array without going through the python list phase, that method is bound to be much faster.  The processing bottleneck is the python list, if one can avoid that things will go faster.