Bagaimana cara kerja Python anydan allfungsinya?
anydan allambil iterables dan kembalikan Truejika ada dan semua (masing-masing) elemen tersebut 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
Jika iterables kosong, anykembaliFalse , dan allkembali True.
>>> any([]), all([])
(False, True)
Saya menunjukkan alldan anyuntuk siswa di kelas hari ini. Mereka sebagian besar bingung tentang nilai kembali untuk iterables kosong. Menjelaskannya dengan cara ini menyebabkan banyak bola lampu menyala.
Perilaku jalan pintas
Mereka, any dan allkeduanya mencari kondisi yang memungkinkan mereka untuk berhenti mengevaluasi. Contoh pertama yang saya berikan mengharuskan mereka untuk mengevaluasi boolean untuk setiap elemen di seluruh daftar.
(Perhatikan bahwa daftar literal tidak dengan sendirinya dievaluasi dengan malas - Anda bisa mendapatkannya dengan Iterator - tetapi ini hanya untuk tujuan ilustrasi.)
Berikut ini adalah implementasi Python dari semua dan semua:
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!
Tentu saja, implementasi nyata ditulis dalam C dan jauh lebih berkinerja, tetapi Anda bisa mengganti yang di atas dan mendapatkan hasil yang sama untuk kode dalam jawaban ini (atau yang lain).
all
allmemeriksa elemen yang akan False(sehingga dapat kembali False), lalu kembali Truejika tidak ada satu pun 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
Cara anykerjanya adalah ia memeriksa elemen yang akan True(sehingga dapat mengembalikan True), then it returnsFalse if 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!
Saya pikir jika Anda mengingat perilaku jalan pintas, Anda akan secara intuitif memahami bagaimana mereka bekerja tanpa harus merujuk pada Tabel Kebenaran.
Bukti alldanany jalan pintas:
Pertama, buat bising_iterator:
def noisy_iterator(iterable):
for i in iterable:
print('yielding ' + repr(i))
yield i
dan sekarang mari kita beralih daftar dengan berisik, menggunakan contoh-contoh kami:
>>> 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
Kita bisa melihat all pemberhentian pada cek boolean False pertama.
Dan anyberhenti pada cek True boolean pertama:
>>> 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
Sumber
Mari kita lihat sumbernya untuk mengkonfirmasi hal di atas.
Inilah sumber untukany :
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;
}
Dan inilah sumber untukall :
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;
}