Selecting a quantity from a list
Your regular Python implementation generally looks reasonable, and unless numpy
offers a performance boost that you really need, I would not recommend it for
this use case: the brevity/clarity tradeoff seems bad.
My biggest suggestion is to consider clearer names. A function with signature
of take_upto_n(A, n) makes me think the function takes an iterable and
returns a sequence of n values. Something like take_upto_sum(A, total)
seems more communicative to me. And even &quot;take&quot; isn't quite right: take
implies a filtering process (we'll take some and leave some). But we
are limiting or capping. Perhaps you can think of something even better.
This example presents a classic Python dilemma: you want to do a simple map
over a list to generate a new list, so of course you would like to knock it out
in a comprehension or something equally cool. But while iterating,
you also need to modify some other variable to keep track of state, and Python
mostly lacks the assignments-as-expression idiom that allows such trickery in
other languages (for example, old-school Perl map/grep one-liners and their
ilk). If you are using a sufficiently modern Python, you can use the walrus
operator to compress the code a bit, but it doesn't get you all the way there.
Honestly, I wouldn't even bother with the walrus (but I would assign min() to
a convenience variable to avoid repetition and thus help readability). In any
case, the walrus approach:
def take_upto_sum(A, total):
    out = []
    for x in A:
        out.append(y := min(total, x))
        total -= y
    return out

I suppose it is possible to express this as a single list comprehension if we
take advantage of the built-in itertools and operator modules. Like the
numpy solution, this approach reminds me of the Spinal Tap quote: It's such a
fine line between stupid, and uh ... clever.
from itertools import accumulate
from operator import sub

def take_upto_sum(A, total):
    return [
        max(min(x, acc), 0)
        for x, acc in zip(A, accumulate(A, sub, initial=total))
    ]