파이썬 any
과 all
함수 는 어떻게 작동합니까?
any
그리고 all
반복 가능 객체을 반환 True
임의의 구성 요소와 (각각) 모든 경우 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
반복 가능 객체가 비어있는 경우 any
반환 False
하고, all
반환 True
.
>>> any([]), all([])
(False, True)
저는 오늘 수업 시간에 학생들을 시연 all
하고 있었습니다 any
. 빈 iterables의 반환 값에 대해 대부분 혼란 스러웠습니다. 이 방법으로 설명하면 많은 전구가 켜졌습니다.
바로 가기 동작
그들은, any
그리고 all
그들을 평가 중지 할 수있는 조건을 모두 찾습니다. 첫 번째 예제에서는 전체 목록의 각 요소에 대한 부울을 평가해야했습니다.
(리스트 리터럴 자체는 게으르게 평가 되지는 않지만 Iterator로 얻을 수는 있지만 설명을위한 것일뿐입니다.)
다음은 모든 파이썬 구현입니다.
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!
물론 실제 구현은 C로 작성되었으며 훨씬 성능이 뛰어나지 만 위의 내용을 대체 하여이 (또는 다른) 답변의 코드에 대해 동일한 결과를 얻을 수 있습니다.
all
all
요소가 있는지 확인 False
(따라서 리턴 할 수 있음 False
) 한 다음 요소 가 True
없으면 리턴 합니다 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
방법의 any
작품은 요소에 대한 그 검사가 될 것입니다 True
그것을 반환 할 수 있도록 ( True), then it returns
거짓 if 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!
지름길을 염두에두면 진리표를 참조하지 않고도 작동 방식을 직관적으로 이해할 수 있다고 생각합니다.
증거 all
및 any
지름길 :
먼저 noisy_iterator를 생성하십시오 :
def noisy_iterator(iterable):
for i in iterable:
print('yielding ' + repr(i))
yield i
이제 예제를 사용하여 목록을 시끄럽게 반복 해 보겠습니다.
>>> 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
all
첫 번째 False boolean check에서 중지를 볼 수 있습니다 .
그리고 any
첫 번째 부울 검사에서 멈 춥니 다.
>>> 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
소스
위의 내용을 확인하기 위해 출처를 살펴 보겠습니다.
소스는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;
}
그리고 여기에 대한 소스가 있습니다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;
}