When should you use a Python list and when should you use array.array or a NumPy array instead?
The reason a list is slower than a typed array comes down to what a list slot holds. A list is an array of pointers to objects, so every integer in it is a separate object with its own memory and its own reference count. A typed array stores the raw values inline, with no per-element object and no reference counting.
That makes array.array the better choice when you have a large number of numbers of the same type. The memory saving is roughly four to eight times for 64-bit values, the cache behaviour is better because the data is contiguous, and there is no per-element object overhead at all.
The catch is that array.array is type-restricted. Its itemsize and typecode are fixed at creation, so you cannot mix an int and a string in one array, and assigning the wrong type raises a TypeError. It also lacks the convenience methods a list has — no append of arbitrary types, and slicing gives you a new array rather than a list.
NumPy goes further and is what you would normally reach for in numerical work. It is not just typed, it is vectorised: operations apply across the whole array without Python-level loops, which is usually a far bigger win than the memory saving. A NumPy array of a million floats uses about eight megabytes and multiplies in milliseconds.
The practical rule for an interview: a list for general-purpose collections of mixed objects, array.array for a large homogeneous sequence of simple values where you want to save memory, and NumPy for anything involving real numerical computation.