5.4.2 · D5Scientific Computing (Python)
Question bank — Array creation — np.zeros, np.ones, np.linspace, np.arange, np.random

True or false — justify
Every "answer" here is the reason, not just the verdict.
np.zeros(3, 4) makes a 3×4 grid of zeros.
False. Shape is ONE argument. The second positional slot is the dtype (the data type), so
4 is read as a (nonsense) dtype and it errors. You must write np.zeros((3, 4)) with the tuple.np.linspace(0, 1, 5) has a step of 1/5 = 0.2.
False. 5 points fence off only 4 gaps (see the top line of the figure), so the step is . Divide by points minus one, never by points.
np.arange(0, 1, 0.25) includes the value 1.0.
False.
arange stop is exclusive, like Python range — that is the hollow amber ring in the figure. It gives [0, 0.25, 0.5, 0.75] and stops before reaching 1.0.np.linspace(0, 1, 5) includes both 0 and 1.
True.
endpoint=True is the default, so both ends are kept (the two filled amber dots) — that is exactly what linspace is for.The default dtype of np.zeros(4) is integer.
False. It is
float64. Scientific math wants floats, so you see 0. not 0. Pass dtype=int if you truly need whole numbers.np.empty(5) returns five zeros.
False. It returns uninitialized memory — whatever bytes were already there (garbage). It only looks like zeros by luck on a fresh page; never rely on it.
np.linspace(0, 10, 10) has step 1.
False. 10 points → 9 gaps → step For a step of exactly 1 use
np.linspace(0, 10, 11) or np.arange(0, 11).Passing the same seed to default_rng always gives the same numbers.
True. The seed fixes the generator's starting state, so the whole sequence is reproducible — that is the entire point of a seed.
np.full((2,2), 7) and np.ones((2,2))*7 give the same result.
True in values, but
np.full says the intent directly and does it in one pass; multiplying ones builds an intermediate array. Prefer full for clarity.Spot the error
Say what is wrong and why, then how to fix it.
out = [] then a loop doing out.append(i**2) — is this the "pro pattern"?
It works but it is the slow pattern: a Python list grows by repeated reallocation. Preallocate with
np.zeros(n) and assign into out[i] so the buffer never moves.np.arange(0, 1, 0.1) — someone asserts it has exactly 10 elements.
Wrong to rely on it.
0.1 is not exact in floating-point, so the accumulated stop test may include or exclude the last value; length can be 10 or 11. Use np.linspace(0, 1, 11) (or 10) when the count matters.np.zeros((3, 4), int) — is int the shape or the dtype?
It is the dtype — the data type in the second positional slot. This is correct and gives an integer 3×4 array of zeros. The trap is only when you forget the tuple around the shape.
rng = np.random.rand(3) — is this the modern generator API?
No —
np.random.rand is the legacy global function sharing hidden state. The modern form is rng = np.random.default_rng(seed) then rng.random(3).np.linspace(5, 0, 4) — will this error because start > stop?
No error.
linspace happily counts downward: the step is negative, giving [5, 3.33, 1.67, 0]. It only cares about producing num evenly spaced points.Why questions
np.linspace divides by num - 1 but np.arange uses ceil((stop - start)/step). Why the different formulas?
linspace is told the count and must compute the gap between fixed endpoints — hence "gaps = points − 1". arange is told the gap and must compute the count of steps that fit before the exclusive stop — hence the ceiling (justified in the next question).Why does arange round up with a ceiling to count its elements?
Because it keeps stepping as long as it is still below
stop. Suppose start = 0, stop = 1, step = 0.3. The exact number of steps is . You cannot take a third-of-a-step, but you do land at — four values, all still under 1. Rounding the up to 4 captures that last partial step's landing point ; rounding down to 3 would wrongly drop it. So counts "every step that starts below stop."Why is np.zeros(10**6) far cheaper than [0]*10**6?
The list stores a million pointers to full Python
int objects; the array is one contiguous typed buffer of raw floats. Less memory, no per-element object overhead, and ready for vectorized math.Why does linspace include the endpoint but arange excludes it?
linspace answers "sample this closed interval " — you want both ends for plotting. arange mimics Python range, whose half-open convention makes lengths add cleanly and avoids double-counting when chaining ranges.Why prefer linspace over arange when you know how many points you need?
arange derives the count from a float step, and float rounding makes that count unreliable. linspace is given the exact count, so it is guaranteed correct regardless of floating-point wobble.Why does np.empty exist if it returns garbage?
It skips the zero-filling pass, so it is the fastest allocator. It is safe only when you immediately overwrite every element — a real speedup in tight preallocate-then-fill code.
Why pass a seed to a random generator at all?
For reproducibility: a teammate or your future self running the same code gets identical "random" numbers, so bugs and results can be replayed exactly.
Edge cases
What does np.linspace(3, 3, 4) return?
[3., 3., 3., 3.]. Start equals stop, so the gap is 0/(4-1)=0; all four points collapse onto 3. No error — just a degenerate (constant) sample.What does np.linspace(0, 1, 0) return?
A valid empty float array of shape
(0,). Asking for zero points is legal — NumPy just returns nothing at all, which lets generic code that computes num on the fly never crash on the num = 0 case.What does np.linspace(0, 1, 1) return?
A single-element array
[0.]. With one point there are zero gaps, so num-1 = 0; NumPy avoids dividing by zero and just returns the start.What does np.arange(5, 0, 1) (positive step, decreasing range) give?
An empty array. With a positive step you can never advance from 5 down to below 0, so zero elements fit before the exclusive stop.
What does np.arange(5, 0, -1) (negative step, decreasing range) give?
[5, 4, 3, 2, 1] — the natural counterpart. A negative step counts down, stopping before the exclusive stop = 0, so 0 itself is dropped. Sign of the step must match the direction from start to stop, or you get the empty array above.What does np.linspace(0, 1, 5, endpoint=False) change?
Now the stop is excluded, so you divide by
num not num-1: step 1/5 = 0.2, giving [0, 0.2, 0.4, 0.6, 0.8]. Useful for periodic sampling where the last point would duplicate the first.What is the length of np.arange(0)?
Zero — an empty array.
arange(0) means "0, 1, … up to but excluding 0", and nothing satisfies that.What is the expected mean of many rng.random() samples, and why?
About
0.5. Uniform draws on are symmetric about the midpoint, so the long-run average sits at ; rng.normal(loc, scale, ...) averages to loc instead.What does np.zeros(0) return?
A valid empty float array of shape
(0,). A length-zero container is legal and often the base case of loops that fill it — not an error.Connections
- 5.4.02 Array creation — np.zeros, np.ones, np.linspace, np.arange, np.random (Hinglish)
- NumPy arrays — shape, dtype, ndim
- Vectorization vs Python loops
- Array indexing and slicing
- Floating-point representation and rounding errors
- Random sampling and distributions
- Plotting functions with Matplotlib