Skip to content

Predicates in itertools and filter #102105

Closed
@pochmann

Description

@pochmann

Documentation

filterfalse

The doc says "Make an iterator that filters elements from iterable returning only those for which the predicate is False". That's not correct, it also returns other false elements:

>>> list(filterfalse(lambda x: x, [False, 0, 1, '', ()]))
[False, 0, '', ()]

quantify

This recipe has the opposite issue:

def quantify(iterable, pred=bool):
    "Count how many times the predicate is true"
    return sum(map(pred, iterable))

It says "true", but it only really works with True. Other predicates, like re.compile(...).match returning re.Match objects or None, don't work and quantify crashes. Predicates returning numbers other than 1 and 0 don't crash it but lead to wrong "counts". So quantify is limited. A pity and an odd outlier, since the other six tools/recipes and filter all support Python's general truth value concept.

The easy fix is to map bool over the predicate values:

def quantify(iterable, pred=bool):
    "Count how many times the predicate is true"
    return sum(map(bool, map(pred, iterable)))

I don't see something "nicer" with the available tools/recipes. If only there was a length recipe, then we could do:

def quantify(iterable, pred=bool):
    "Count how many times the predicate is true"
    return length(filter(pred, iterable))

filter

The doc says:

filter(function, iterable)
Construct an iterator from those elements of iterable for which function returns true.

The "returns true" doesn't work well. I'd say "returns a true value" or "for which function is true".

The last paragraph has the same issue:

See itertools.filterfalse() for the complementary function that returns elements of iterable for which function returns false.

Linked PRs

Metadata

Metadata

Assignees

Labels

docsDocumentation in the Doc dir

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions