np.array is compiled, and something of a black box. It works predictably for lists of lists of numbers, provided it can make multidimensional array. The fall back is an object dtype array (array of lists), or in some cases an error (Creating numpy array problem ( could not broadcast input array from shape (2) into shape (1) )).
np.stackis a cover function for np.concatenate. It's python code.
First it makes all inputs arrays:
arrays = [asanyarray(arr) for arr in arrays]
asanyarray is just a no-copy call to np.array.
Then it checks the shapes - they must all be the same
shapes = {arr.shape for arr in arrays}
then it adds a dimension to each (details omitted)
expanded_arrays = [arr[sl] for arr in arrays]
and concatenates them:
concatenate(expanded_arrays, axis=axis, out=out)
Starting from a list of arrays, it does about the same amount of work as np.array (timings are similar for large lists). As the other answer noted, it won't give a ragged array. But where stack is really nice is when we want to use axis. Without that we'd have to transpose the array version.