Chris Angelico wrote: > On Wed, Mar 7, 2018 at 2:12 AM, Kirill Balunov <kirillbalu...@gmail.com> > wrote: >> >> >> 2018-03-06 17:55 GMT+03:00 Chris Angelico <ros...@gmail.com>: >>> >>> On Wed, Mar 7, 2018 at 1:48 AM, Kirill Balunov <kirillbalu...@gmail.com> >>> wrote: >>> > Note: For some historical reasons as the first argument you can use >>> > None instead of function, in this case the identity function is >>> > assumed. That is, all elements of iterable that are false are removed >>> > which is equivalent >>> > to (item for item in iterable if item). Currently, for the same >>> > purpose the >>> > preferred form is `filter(bool, iterable)`. >>> > >>> >>> I'd prefer to word it something like: >>> >>> If the first argument is None, the identity function is assumed. That >>> is, all elements of the iterable that are false are removed; it is >>> equivalent to (item for item in iterable if item). It is approximately >>> equivalent to (but faster than) filter(bool, iterable). >>> >>> ChrisA >>> -- >>> https://mail.python.org/mailman/listinfo/python-list >> >> >> I do not want to seem rude and stubborn, but how much faster is it to >> highlight or emphasize it: >> > > Timings mean little. Why do we write: > > if lst: > > instead of: > > if bool(lst): > > ? Because it's unnecessary and pointless to call bool() on something > before using it in a boolean context. If that concept causes you > problems, it's not the fault of the filter function; filter simply > uses something in a boolean context. > > So "the identity function" is more correct than "the bool() function".
Fun fact: CPython handles filter(bool) and filter(None) the same way, it sets the checktrue flag and chooses the fast path: static PyObject * filter_next(filterobject *lz) { PyObject *item; PyObject *it = lz->it; long ok; PyObject *(*iternext)(PyObject *); int checktrue = lz->func == Py_None || lz->func == (PyObject *)&PyBool_Type; iternext = *Py_TYPE(it)->tp_iternext; for (;;) { item = iternext(it); if (item == NULL) return NULL; if (checktrue) { ok = PyObject_IsTrue(item); } else { PyObject *good; good = PyObject_CallFunctionObjArgs(lz->func, item, NULL); if (good == NULL) { Py_DECREF(item); return NULL; } ok = PyObject_IsTrue(good); Py_DECREF(good); } if (ok > 0) return item; Py_DECREF(item); if (ok < 0) return NULL; } } If there were a built-in identity() function it could be treated the same way. -- https://mail.python.org/mailman/listinfo/python-list