]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.11] Backport itertool recipe updates (GH-102881)
authorRaymond Hettinger <rhettinger@users.noreply.github.com>
Tue, 21 Mar 2023 18:44:32 +0000 (13:44 -0500)
committerGitHub <noreply@github.com>
Tue, 21 Mar 2023 18:44:32 +0000 (13:44 -0500)
Doc/library/itertools.rst

index 5fe93fd3e0e5f094e20b536a51fb03eaebc978e2..e1ffd39b1bd815050b7f4be4849ac14aa1020a8c 100644 (file)
@@ -805,7 +805,7 @@ which incur interpreter overhead.
        if n < 1:
            raise ValueError('n must be at least one')
        it = iter(iterable)
-       while (batch := tuple(islice(it, n))):
+       while batch := tuple(islice(it, n)):
            yield batch
 
    def grouper(iterable, n, *, incomplete='fill', fillvalue=None):
@@ -861,11 +861,23 @@ which incur interpreter overhead.
           (x - 5) (x + 4) (x - 3)  expands to:   x³ -4x² -17x + 60
        """
        # polynomial_from_roots([5, -4, 3]) --> [1, -4, -17, 60]
-       roots = list(map(operator.neg, roots))
-       return [
-           sum(map(math.prod, combinations(roots, k)))
-           for k in range(len(roots) + 1)
-       ]
+       expansion = [1]
+       for r in roots:
+           expansion = convolve(expansion, (1, -r))
+       return list(expansion)
+
+   def polynomial_eval(coefficients, x):
+       """Evaluate a polynomial at a specific value.
+
+       Computes with better numeric stability than Horner's method.
+       """
+       # Evaluate x³ -4x² -17x + 60 at x = 2.5
+       # polynomial_eval([1, -4, -17, 60], x=2.5) --> 8.125
+       n = len(coefficients)
+       if n == 0:
+           return x * 0  # coerce zero to the type of x
+       powers = map(pow, repeat(x), reversed(range(n)))
+       return sumprod(coefficients, powers)
 
    def iter_index(iterable, value, start=0):
        "Return indices where a value occurs in a sequence or iterable."