Python Forum
incremental testing in all() - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: incremental testing in all() (/thread-20525.html)

Pages: 1 2


incremental testing in all() - Skaperen - Aug-15-2019

i have a huge list that i want to test that everything is an expected type. i could test it like this:
    if all(isinstance(x,types) for x in huge_list):
        ... # what to do if all items are a type of one of "types"
    else:
        ... # what to do if one or more items are not a type of one of "types"
what i want to know is if all() quits early if one of its tests comes up False. documentation shows code that returns early. i want to know if "equivalent" really means that behavior or if it just means the result is "equivalent".


RE: incremental testing in all() - boring_accountant - Aug-16-2019

According to the Python docs, all() does quit early.
Quote:all(iterable)ΒΆ
Return True if all elements of the iterable are true (or if the iterable is empty). Equivalent to:

def all(iterable):
    for element in iterable:
        if not element:
            return False
    return True



RE: incremental testing in all() - Skaperen - Aug-17-2019

i see you didn't get the semantics of my post.


RE: incremental testing in all() - buran - Aug-17-2019

Or you didn't get the semantics of the docs? It quit early. if it does not, it would not be "Equivalent" to the code in the docs.


RE: incremental testing in all() - perfringo - Aug-17-2019

Everyone has access not only 'equivalent' but also 'exact' code.

Go to https://github.com/python/cpython/blob/master/Python/bltinmodule.c and look for builtin_all. For your convenience it's provided below (I am not C-man myself so I have no idea what does it mean Smile ):

static PyObject *
builtin_all(PyObject *module, PyObject *iterable)
/*[clinic end generated code: output=ca2a7127276f79b3 input=1a7c5d1bc3438a21]*/
{
    PyObject *it, *item;
    PyObject *(*iternext)(PyObject *);
    int cmp;

    it = PyObject_GetIter(iterable);
    if (it == NULL)
        return NULL;
    iternext = *Py_TYPE(it)->tp_iternext;

    for (;;) {
        item = iternext(it);
        if (item == NULL)
            break;
        cmp = PyObject_IsTrue(item);
        Py_DECREF(item);
        if (cmp < 0) {
            Py_DECREF(it);
            return NULL;
        }
        if (cmp == 0) {
            Py_DECREF(it);
            Py_RETURN_FALSE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_TRUE;
}



RE: incremental testing in all() - Gribouillis - Aug-17-2019

The C code proves that it returns early. Note that the macro Py_RETURN_FALSE used at line 26 above is defined in Include/boolobject.h

#define Py_RETURN_FALSE return Py_INCREF(Py_False), Py_False



RE: incremental testing in all() - Skaperen - Aug-18-2019

(Aug-17-2019, 06:01 AM)buran Wrote: Or you didn't get the semantics of the docs? It quit early. if it does not, it would not be "Equivalent" to the code in the docs.

it's saying that in the context of describing the value being returned. so, it can still be either way and the wording of the document would still be correct. some code that is able to test this would be nice, if the document doesn't have a clarification.


RE: incremental testing in all() - buran - Aug-18-2019

(Aug-18-2019, 07:10 PM)Skaperen Wrote: it's saying that in the context of describing the value being returned. so, it can still be either way and the wording of the document would still be correct.
I beg to disagree. If it does not quit early it would not be equivalent to provided code. But as others pointed out, you can check the source code to your satisfaction.


RE: incremental testing in all() - Skaperen - Aug-18-2019

if it does not quit early it can still be equivalent to that code in terms of what is returned. that semantic is the effect of a sentence in context. this was learned in my basic journalism writing class (a good class to take for documentive writing). perhaps i should write a couple replacement paragraphs. but, this is not the only ambiguity i have seen in the documentation. English is an expressive language, not an inflexive one, such as Norwegian or Spanish. word order and context are part of the language, not the culture as is the case with most others. try Esperanto, it is the most inflexive language i have seen, despite being artificial.

i did put together a little brute-force test with a 268435460 size tuple. it did show the early quit. i saw the early quit in the C code. despite the high probability of it being so, that does not prove that the binary i'm running matches that source (Ubuntu has changed things before).


RE: incremental testing in all() - DeaD_EyE - Aug-18-2019

Here the proof without have to read C.

deadeye@nexus ~ $ ipython                                                                                                       
Python 3.7.4 (default, Jul 10 2019, 23:32:01) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.7.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: class Iterator: 
   ...:     def __init__(self): 
   ...:         self.last = None 
   ...:          
   ...:     def __iter__(self): 
   ...:         for i in range(10): 
   ...:             print(i) 
   ...:             if i < 5: 
   ...:                 yield True 
   ...:             else: 
   ...:                 yield False 
   ...:                                                                                                                         

In [2]: all(Iterator())                                                                                                         
0
1
2
3
4
5
Out[2]: False
The loop is stopped, when False is yielded.