This is a really good example of how the range of variable types in Python and numpy can be confusing for a beginner. What's happening is [3,1,4,8,2,1,0] returns a list, not an ndarray. So, the expression ar == 8 returns a scalar False, because all comparisons between list and scalar types return False. Thus, np.where(False) returns an empty array. The way to fix this is:
arr = np.array([3,1,4,8,2,1,0])
np.where(arr == 8)
This returns (array([3]),). There's opportunity for further confusion, because where returns a tuple. If you write a script that intends to access the index position (3, in this case), you need np.where(arr == 8)[0] to pull the first (and only) result out of the tuple. To actually get the value 3, you need np.where(arr == 8)[0][0] (although this will raise an IndexError if there are no 8's in the array).
This is an example where numeric-specialized languages like Matlab or Octave are simpler to use for purely numerical applications, because the language is less general and so has fewer return types to understand.