Skip to content

Accumulators

graph TD
  Z(["<code>sum(iterable, initial=initial, default=default)</code>"]) --> A{"<code>initial</code> <code>MISSING</code>?"};
  A --> |no| B["<code>return initial+...</code>"];
  A --> |yes| C{"<code>iterable</code> empty?"};
  C --> |no| D["<code>return iterable[0]+...</code>"];
  C --> |yes| E{"<code>default</code> <code>MISSING</code>?"};
  E --> |no| F["<code>return default</code>"];
  E --> |yes| G["<code>raise TypeError</code>"];

MISSING module-attribute

MISSING = object()

Sentinel to mark empty parameters.

group_ordinal

group_ordinal(*iterables)

Group elements of iterables by their ordinal.

>>> iterables = (1, 2, 3), [4, 5, 6, 7], {8}
>>> list(group_ordinal(*iterables))
[(1, 4, 8), (2, 5), (3, 6), (7,)]

The elements are grouped in the same order as their iterables (stable).

References
Source code in operationcounter\accumulators.py
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def group_ordinal(*iterables):
    """Group elements of iterables by their ordinal.

        >>> iterables = (1, 2, 3), [4, 5, 6, 7], {8}
        >>> list(group_ordinal(*iterables))
        [(1, 4, 8), (2, 5), (3, 6), (7,)]

    The elements are grouped in the same order as their iterables (stable).

    References
    ----------
    - <https://github.com/more-itertools/more-itertools/pull/1073>
    """
    iterators = list(map(iter, reversed(iterables)))
    result = []
    while iterators:
        result.clear()
        for i in reversed(range(len(iterators))):
            try:
                result.append(next(iterators[i]))
            except StopIteration:
                del iterators[i]
        if result:
            yield tuple(result)

reduce_default

reduce_default(
    function, iterable, *, initial=MISSING, default=0
)

Apply function of two arguments cumulatively to the iterable.

Like functools.reduce but with an optional initial element and an optional default return value. Difference to functools.reduce:

  • If iterable is empty and initial and default are MISSING, a TypeError is raised.
  • If iterable is empty and initial is MISSING, but default is not, then default is returned.
Source code in operationcounter\accumulators.py
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
def reduce_default(function, iterable, *, initial=MISSING, default=0):
    """Apply function of two arguments cumulatively to the iterable.

    Like `functools.reduce` but with an optional initial element and an
    optional default return value.
    Difference to `functools.reduce`:

    - If `iterable` is empty and `initial` and `default` are `MISSING`, a
      `TypeError` is raised.
    - If `iterable` is empty and `initial` is `MISSING`, but `default` is not,
      then `default` is returned.
    """
    if initial is not MISSING:
        return reduce(function, iterable, initial)
    else:
        it = iter(iterable)
        try:
            initial = next(it)
        except StopIteration:
            if default is not MISSING:
                return default
            else:
                raise TypeError("accumulation of empty iterable with no" \
                        + " initial or default value")
        return reduce(function, it, initial)

sum_default

sum_default(iterable, *, initial=MISSING, default=0)

Return the sum of all elements in the iterable.

Like sum but with an optional initial element and an optional default return value.

  • If iterable is empty and initial and default are MISSING, a TypeError is raised.
  • If iterable is empty and initial is MISSING, but default is not, then default is returned.
  • If initial is MISSING, then there is truly no initial 0+=.
Source code in operationcounter\accumulators.py
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
def sum_default(iterable, *, initial=MISSING, default=0):
    """Return the sum of all elements in the iterable.

    Like `sum` but with an optional initial element and an optional default
    return value.

    - If `iterable` is empty and `initial` and `default` are `MISSING`, a
      `TypeError` is raised.
    - If `iterable` is empty and `initial` is `MISSING`, but `default` is not,
      then `default` is returned.
    - If `initial` is `MISSING`, then there is truly no initial `0+=`.
    """
    if initial is not MISSING:
        return sum(iterable, initial)
    else:
        it = iter(iterable)
        try:
            initial = next(it)
        except StopIteration:
            if default is not MISSING:
                return default
            else:
                raise TypeError("accumulation of empty iterable with no" \
                        + " initial or default value")
        return sum(it, start=initial)

prod_default

prod_default(iterable, *, initial=MISSING, default=1)

Return the product of all elements in the iterable.

Like math.prod but with an optional initial element and an optional default return value.

  • If iterable is empty and initial are default is MISSING, a TypeError is raised.
  • If iterable is empty and initial is MISSING, but default is not, then default is returned.
  • If initial is MISSING, then there is truly no initial 1*=.
Source code in operationcounter\accumulators.py
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
def prod_default(iterable, *, initial=MISSING, default=1):
    """Return the product of all elements in the iterable.

    Like `math.prod` but with an optional initial element and an optional
    default return value.

    - If `iterable` is empty and `initial` are `default` is `MISSING`, a
      `TypeError` is raised.
    - If `iterable` is empty and `initial` is `MISSING`, but `default` is not,
      then `default` is returned.
    - If `initial` is `MISSING`, then there is truly no initial `1*=`.
    """
    #don't use math.prod, as it may reject non-numeric values
    return reduce_default(mul, iterable, initial=initial, default=default)

sumprod_default

sumprod_default(a, b, *, initial=MISSING, default=0)

Return the sum-product of all elements in the iterables.

Like math.sumprod but with an optional initial element, an optional default return value and non-strict zipping of both iterables.

  • If a or b is empty and initial and default are MISSING, a TypeError is raised.
  • If a or b is empty and initial is MISSING, but default is not, then default is returned.
  • If initial is MISSING, then there is truly no initial 0+=.
Source code in operationcounter\accumulators.py
104
105
106
107
108
109
110
111
112
113
114
115
116
def sumprod_default(a, b, *, initial=MISSING, default=0):
    """Return the sum-product of all elements in the iterables.

    Like `math.sumprod` but with an optional initial element, an optional
    default return value and non-strict zipping of both iterables.

    - If `a` or `b` is empty and `initial` and `default` are `MISSING`, a
      `TypeError` is raised.
    - If `a` or `b` is empty and `initial` is `MISSING`, but `default` is not,
      then `default` is returned.
    - If `initial` is `MISSING`, then there is truly no initial `0+=`.
    """
    return sum_default(map(mul, a, b), initial=initial, default=default)