Î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?
- 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.
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
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.
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'])]
- @ 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 – > .
- @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. – > .
Cum funcționează Python’s
any
șiall
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 all
caută 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 returns
Falseif none of them were
True`.
>>> 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;
}
- 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 – > .
- @thanos.a it’s in
Python/bltinmodule.c
– Am adăugat-o la cele de mai sus. – > .
Ș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.
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.
- Colbert’s ajunge la CS/CE: en.wikipedia.org/wiki/Truthiness ? Vorbim de logică neclară? 😀 – > .
- Așa cum a cerut OP
True
atunci când valorile sunt diferite, lungimea setului trebuie să fie 2, nu 1. – > . - @wombatonfire haha bună observație. Am ajustat răspunsul meu vechi de 7 ani 🙂 – > .
- Răspunsurile bune nu îmbătrânesc 🙂 Frumoasă abordare cu un set. – > .
>>> any([False, False, False])
False
>>> any([False, True, False])
True
>>> all([False, True, True])
False
>>> all([True, True, True])
True
s = "eFdss"
s = list(s)
all(i.islower() for i in s ) # FALSE
any(i.islower() for i in s ) # TRUE
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
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 .