Python'lar anyve allfonksiyonlar nasıl çalışır?
anyve allyinelenebilirleri alın ve Trueöğelerin herhangi biri (tümü) ise geri dönün 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
Yinelenebilirler boşsa, anygeri döner Falseve allgeri döner True.
>>> any([]), all([])
(False, True)
Ben gösteren edildi allve anysınıftaki öğrencilere bugün için. Çoğunlukla boş tekrarlanabilirler için dönüş değerleri konusunda kafası karışıktı. Bu şekilde açıklamak birçok ampulün yanmasına neden oldu.
Kısayol davranışı
Onlar anyve allonları değerlendiren durdurmak için izin veren bir durum için her iki bakış. Verdiğim ilk örnekler, tüm listedeki her bir öğe için boole değerlerini değerlendirmelerini gerektiriyordu.
(Liste değişmezine dikkat edin bilgisinin kendisinin tembel olarak değerlendirilmediğine dikkat edin - bunu bir Yineleyici ile alabilirsiniz - ancak bu yalnızca açıklama amaçlıdır.)
İşte tüm Python uygulamaları:
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!
Tabii ki, gerçek uygulamalar C ile yazılır ve çok daha performanslıdır, ancak yukarıdakilerin yerine geçebilir ve bu (veya başka herhangi bir) cevaptaki kod için aynı sonuçları alabilirsiniz.
all
allöğelerin olup olmadığını kontrol eder False(böylece geri dönebilir False), sonra Truehiçbiri olmadıkça geri döner 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
Yolu anyişleri elemanlarının aynı çekleri olmak olmasıdır Trueo dönebilmek ( True), then it returnsYanlışif none of them were etmesidir True`ya dönebilir.
>>> 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!
Kısa devre davranışını aklınızda tutarsanız, bir Doğruluk Tablosuna başvurmak zorunda kalmadan sezgisel olarak nasıl çalıştıklarını anlayacaksınız.
Kanıtı all ve anykısayol:
İlk olarak, bir noisy_iterator oluşturun:
def noisy_iterator(iterable):
for i in iterable:
print('yielding ' + repr(i))
yield i
ve şimdi örneklerimizi kullanarak gürültülü listeler üzerinden tekrarlayalım:
>>> 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
Görebiliriz allİlk Yanlış boole kontrolünde durakları .
Ve anyilk Gerçek boole kontrolünde durur:
>>> 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
Kaynak
Yukarıdakileri doğrulamak için kaynağa bakalım.
İşte kaynağı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;
}
Ve işte kaynakall :
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;
}