Cum funcționează funcțiile any și all din Python? (Programare, Python)

O.rka a intrebat.

Încerc să înțeleg cum funcționează funcțiile any() și all() funcționează funcțiile încorporate în Python.

Încerc să compar tuplurile astfel încât, dacă orice valoare este diferită, atunci se va returna True iar dacă toate sunt la fel, va returna False. Cum funcționează în acest caz pentru a returna [False, False, False, False]?

d este un defaultdict(list).

print d['Drd2']
# [[1, 5, 0], [1, 6, 0]]
print list(zip(*d['Drd2']))
# [(1, 1), (5, 6), (0, 0)]
print [any(x) and not all(x) for x in zip(*d['Drd2'])]
# [False, False, False]

Din câte știu eu, acest lucru ar trebui să producă

# [False, True, False]

deoarece (1,1) sunt identice, (5,6) sunt diferite, iar (0,0) sunt identice.

De ce se evaluează la False pentru toate tuplurile?

Comentarii

  • any(iterable) : returnează true la prima întâlnire a obiectului Truthy else returnează false. all(iterable): returnează flase la prima întâlnire a obiectului falsy else returnează true. –  > Por shadow0359.
8 răspunsuri
thefourtheye

Vă puteți gândi în linii mari la any și all ca pe o serie de serii de logică or și and și, respectiv, operatori logici.

orice

any va returna True atunci când cel puțin unul dintre elementele este Adevărat. Citește despre Testarea valorii de adevăr.

toate

all va returna True numai atunci când toate elementele sunt adevărate.

Tabel de adevăr

+-----------------------------------------+---------+---------+
|                                         |   any   |   all   |
+-----------------------------------------+---------+---------+
| All Truthy values                       |  True   |  True   |
+-----------------------------------------+---------+---------+
| All Falsy values                        |  False  |  False  |
+-----------------------------------------+---------+---------+
| One Truthy value (all others are Falsy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| One Falsy value (all others are Truthy) |  True   |  False  |
+-----------------------------------------+---------+---------+
| Empty Iterable                          |  False  |  True   |
+-----------------------------------------+---------+---------+

Nota 1: Cazul iterabilelor goale este explicat în documentația oficială, astfel

any

Return True dacă orice element al iterabilului este adevărat. În cazul în care iterabilul este gol, se returnează False

Deoarece niciunul dintre elemente nu este adevărat, se returnează False în acest caz.

all

Return True în cazul în care toate elementele iterabilului sunt adevărate (sau dacă iterabilul este gol).

Deoarece niciunul dintre elemente nu este fals, se returnează True în acest caz.


Nota 2:

Un alt lucru important de știut despre any și all este că va scurtcircuita execuția, în momentul în care va cunoaște rezultatul. Avantajul este că nu este necesar să se consume întregul iterabil. De exemplu,

>>> multiples_of_6 = (not (i % 6) for i in range(1, 10))
>>> any(multiples_of_6)
True
>>> list(multiples_of_6)
[False, False, False]

Aici, (not (i % 6) for i in range(1, 10)) este o expresie generatoare care returnează True dacă numărul curent cuprins între 1 și 9 este un multiplu de 6. any iterați multiples_of_6 și când întâlnește 6, găsește o valoare Adevărat, deci returnează imediat True, iar în rest multiples_of_6 nu este iterat. Aceasta este ceea ce vedem atunci când imprimăm list(multiples_of_6), rezultatul lui 7, 8 și 9.

Acest lucru excelent este folosit foarte inteligent în acest răspuns.


Cu această înțelegere de bază, dacă ne uităm la codul dvs.

any(x) and not all(x)

care se asigură că, cel puțin una dintre valori este Adevărat, dar nu toate. Acesta este motivul pentru care se returnează [False, False, False]. Dacă ați fi vrut cu adevărat să verificați dacă ambele numere nu sunt identice,

print [x[0] != x[1] for x in zip(*d['Drd2'])]

Comentarii

  • @ oricine: dacă am nevoie să folosesc toate, dar cazul în care returnează True pentru lista goală nu este acceptabil, ce facem? Nu înțeleg logica din spatele faptului că dă True dacă lista este goală… adică all([]) == True –  > Por JavaSa.
  • @JavaSa Puteți verifica în mod explicit dacă lista este goală. Cred că ceva de genul bool(data) and all(...) ar trebui să funcționeze. –  > Por thefourtheye.
Aaron Hall

Cum funcționează Python’s any și all funcționează funcțiile?

any și all iau iterabile și returnează True dacă oricare și toate (respectiv toate) elementele sunt True.

>>> any([0, 0.0, False, (), '0']), all([1, 0.0001, True, (False,)])
(True, True)            #   ^^^-- truthy non-empty string
>>> any([0, 0.0, False, (), '']), all([1, 0.0001, True, (False,), {}])
(False, False)                                                #   ^^-- falsey

În cazul în care iterabilele sunt goale, any returnează False, și all returnează True.

>>> any([]), all([])
(False, True)

Am demonstrat că all și any pentru elevii din clasă astăzi. Aceștia au fost în mare parte confuzi cu privire la valorile de returnare pentru iterabilele goale. Explicarea în acest mod a făcut ca o mulțime de beculețe să se aprindă.

Scurtarea comportamentului

Ei, any și allcaută amândouă o condiție care să le permită să oprească evaluarea. Primele exemple pe care le-am dat le cereau să evalueze booleanul pentru fiecare element din întreaga listă.

(Rețineți că literalul listei nu este ea însăși evaluată în mod leneș – ați putea obține acest lucru cu un Iterator – dar acest lucru este doar în scop ilustrativ).

Iată o implementare Python a oricărui și tuturor:

def any(iterable):
    for i in iterable:
        if i:
            return True
    return False # for an empty iterable, any returns False!

def all(iterable):
    for i in iterable:
        if not i:
            return False
    return True  # for an empty iterable, all returns True!

Desigur, implementările reale sunt scrise în C și sunt mult mai performante, dar ați putea înlocui cele de mai sus și obține aceleași rezultate pentru codul din acest răspuns (sau orice alt răspuns).

all

all verifică dacă elementele trebuie să fie False (astfel încât să poată returna False), apoi returnează True dacă niciunul dintre ele nu a fost False.

>>> all([1, 2, 3, 4])                 # has to test to the end!
True
>>> all([0, 1, 2, 3, 4])              # 0 is False in a boolean context!
False  # ^--stops here!
>>> all([])
True   # gets to end, so True!

any

Modul în care any funcționează este că verifică dacă elementele trebuie să fie True (astfel încât să poată returna True), then it returnsFalseif none of them wereTrue`.

>>> any([0, 0.0, '', (), [], {}])     # has to test to the end!
False
>>> any([1, 0, 0.0, '', (), [], {}])  # 1 is True in a boolean context!
True   # ^--stops here!
>>> any([])
False   # gets to end, so False!

Cred că dacă țineți cont de comportamentul de scurtare, veți înțelege intuitiv cum funcționează fără a fi nevoie să faceți referire la un tabel de adevăr.

Dovadă că all și any scurtătură:

Mai întâi, creați un noisy_iterator:

def noisy_iterator(iterable):
    for i in iterable:
        print('yielding ' + repr(i))
        yield i

și acum să iterăm peste liste în mod zgomotos, folosind exemplele noastre:

>>> all(noisy_iterator([1, 2, 3, 4]))
yielding 1
yielding 2
yielding 3
yielding 4
True
>>> all(noisy_iterator([0, 1, 2, 3, 4]))
yielding 0
False

Putem vedea all se oprește la prima verificare booleană False.

Și any se oprește la prima verificare booleană adevărată:

>>> any(noisy_iterator([0, 0.0, '', (), [], {}]))
yielding 0
yielding 0.0
yielding ''
yielding ()
yielding []
yielding {}
False
>>> any(noisy_iterator([1, 0, 0.0, '', (), [], {}]))
yielding 1
True

Sursa

Să ne uităm la sursă pentru a confirma cele de mai sus.

Iată sursa sursă pentru any:

static PyObject *
builtin_any(PyObject *module, PyObject *iterable)
{
    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_TRUE;
        }
    }
    Py_DECREF(it);
    if (PyErr_Occurred()) {
        if (PyErr_ExceptionMatches(PyExc_StopIteration))
            PyErr_Clear();
        else
            return NULL;
    }
    Py_RETURN_FALSE;
}

Și iată sursa sursa pentru all:

static PyObject *
builtin_all(PyObject *module, PyObject *iterable)
{
    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;
}

Comentarii

  • Notă: acest lucru este în concordanță cu predicatele matematice: „pentru toți” și „există”. Confuzia poate fi dată de faptul că „PENTRU TOȚI” și „PENTRU ORICE” sunt sinonime în alte contexte… ro.wikipedia.org/wiki/List_of_logic_symbols –  > Por mcoolive.
  • @thanos.a it’s in Python/bltinmodule.c – Am adăugat-o la cele de mai sus. –  > Por Aaron Hall.
Arthur Tacca

Știu că este veche, dar m-am gândit că ar putea fi util să arăt cum arată aceste funcții în cod. Acest lucru ilustrează cu adevărat logica, mai bine decât un text sau un tabel IMO. În realitate, ele sunt implementate în C mai degrabă decât în Python pur, dar acestea sunt echivalente.

def any(iterable):
    for item in iterable:
        if item:
            return True
    return False

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

În special, puteți vedea că rezultatul pentru iterabile goale este doar rezultatul natural, nu un caz special. De asemenea, puteți vedea comportamentul de scurtcircuitare; de fapt, ar fi mai mult de lucru pentru acolo nu să nu existe scurtcircuitare.

Atunci când Guido van Rossum (creatorul Python) a propus pentru prima dată adăugarea any() și all(), el le-a explicat prin simpla postare a exact fragmente de cod de mai sus.

roippi

Codul în cauză despre care întrebi provine din răspunsul meu dat aici. Acesta a fost menit să rezolve problema comparării matricelor de mai mulți biți – adică a colecțiilor de 1 și 0.

any și all sunt utile atunci când vă puteți baza pe „veridicitatea” valorilor – adică pe valoarea lor într-un context boolean. 1 este True și 0 este False, o comoditate pe care acest răspuns a valorificat-o. Se întâmplă ca 5 să fie și True, așa că atunci când amestecați asta în intrările posibile… ei bine. Nu merge.

Ai putea în schimb să faci ceva de genul ăsta:

[len(set(x)) > 1 for x in zip(*d['Drd2'])]

Îi lipsește estetica răspunsului anterior (I într-adevăr plăcut aspectul de any(x) and not all(x)), dar își face treaba.

Comentarii

  • Colbert’s ajunge la CS/CE: en.wikipedia.org/wiki/Truthiness ? Vorbim de logică neclară? 😀 –  > Por Geof Sawaya.
  • Așa cum a cerut OP True atunci când valorile sunt diferite, lungimea setului trebuie să fie 2, nu 1. –  > Por wombatonfire.
  • @wombatonfire haha bună observație. Am ajustat răspunsul meu vechi de 7 ani 🙂 –  > Por roippi.
  • Răspunsurile bune nu îmbătrânesc 🙂 Frumoasă abordare cu un set. –  > Por wombatonfire.
Jobin
>>> any([False, False, False])
False
>>> any([False, True, False])
True
>>> all([False, True, True])
False
>>> all([True, True, True])
True

David Gladson
s = "eFdss"
s = list(s)
all(i.islower() for i in s )   # FALSE
any(i.islower() for i in s )   # TRUE

DK250

Conceptul este simplu:

M =[(1, 1), (5, 6), (0, 0)]

1) print([any(x) for x in M])
[True, True, False] #only the last tuple does not have any true element

2) print([all(x) for x in M])
[True, True, False] #all elements of the last tuple are not true

3) print([not all(x) for x in M])
[False, False, True] #NOT operator applied to 2)

4) print([any(x)  and not all(x) for x in M])
[False, False, False] #AND operator applied to 1) and 3)
# if we had M =[(1, 1), (5, 6), (1, 0)], we could get [False, False, True]  in 4)
# because the last tuple satisfies both conditions: any of its elements is TRUE 
#and not all elements are TRUE 

Ajmal Aamir
list = [1,1,1,0]
print(any(list)) # will return True because there is  1 or True exists
print(all(list)) # will return False because there is a 0 or False exists
return all(a % i for i in range(3, int(a ** 0.5) + 1)) # when number is divisible it will return False else return True but the whole statement is False .

Tags: