[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Do not promote `None` as the first argument to `filter` in documentation.

On Tue, Mar 6, 2018 at 7:52 PM, Kirill Balunov <kirillbalunov at gmail.com> wrote:
> This thought occurred to me several times, but I could not decide to write.
> And since `filter` is a builtin, I think this change should be discussed
> here, before opening an issue on bug tracker.
> I propose to delete all references in the `filter` documentation that the
> first argument can be `None`, with possible depreciation of `None` as the
> the first argument - FutureWarning in Python 3.8+ and deleting this option
> in Python 4. Personally, regarding the last point - depreciation, I do not
> see this as a great necessity, but I do not find that the option with `None`
> should be offered and suggested through the documentation. Instead, it is
> better to show an example with using `filter(bool, iterable)` which is
> absolutely
> equivalent, more readable, but a little bit slower.
> %timeit [*filter(None, range(10))]
> 503 ns ? 0.259 ns per loop (mean ? std. dev. of 7 runs, 1000000 loops each)
> %timeit [*filter(bool, range(10))]
> 512 ns ? 1.09 ns per loop (mean ? std. dev. of 7 runs, 1000000 loops each)
> Currently documentation for `None` case uses `identity function is
> assumed`, what is this `identity` and how it is consistent with
> truthfulness?

The identity function is:

filter(lambda x: x, range(10))

How is it consistent with truthiness? Exactly the same way the
underlying object is. There's no requirement for the predicate
function to return True or False - it's perfectly acceptable, for
instance, to do this:

filter(lambda x: x % 3, range(10))

to eliminate all multiples of three.

That said, though, any use of filter() that involves a lambda function
should probably become list comps or genexps, so filter itself should
only be used when there really IS a pre-existing function that does
the job. So, for instance, you could strip out every occurrence of the
string "0" with:

filter(int, list_of_strings)

And that still depends on the normal Python rules for boolification.
If that's valid, then it should be just as viable to say
"filter(identity-function, ...)", which is spelled "filter(None,