파이썬의 모든 기능은 어떻게 작동합니까?


225

나는 방법을 이해하기 위해 노력하고있어 any()all()파이썬 내장 함수 작동합니다.

값이 다르면 반환 True되고 모두 동일하면 반환 되도록 터플을 비교하려고합니다 False. 이 경우에 [False, False, False]를 반환하기 위해 어떻게 노력하고 있습니까?

d입니다 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]

내 지식으로는 이것이 출력되어야합니다.

# [False, True, False]

(1,1)이 같고 (5,6)이 다르며 (0,0)이 동일하기 때문입니다.

모든 튜플에 대해 False로 평가하는 이유는 무엇입니까?


4
any (iterable) : Truthy 객체가 처음 발견되면 true를, 그렇지 않으면 false를 반환합니다. all (iterable) : 잘못된 객체가 처음 발생할 때 flase를 반환하고 그렇지 않으면 true를 반환합니다.
shadow0359

답변:


375

당신은 대략 생각할 수 anyall논리의 일련의 orand각각 운영.

어떤

any요소 중 하나 이상 이 Truthy True 경우 반환 됩니다 . 진실 가치 테스트 에 대해 읽어보십시오 .

모두

all모든 요소 가 Truthy 인 True경우에만 반환 됩니다 .

진실 표

+-----------------------------------------+---------+---------+
|                                         |   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   |
+-----------------------------------------+---------+---------+

참고 1 : 빈 반복 가능한 사례는 공식 문서에 다음과 같이 설명되어 있습니다.

any

Trueiterable의 요소가 참이면 리턴 합니다. iterable이 비어 있으면 리턴False

어떤 요소도 참이 아니기 False때문에이 경우에 반환 됩니다.

all

Trueiterable의 모든 요소가 true ( 또는 iterable이 비어있는 경우 )를 리턴 합니다 .

어떤 요소도 거짓이 아니기 True때문에이 경우에 반환 됩니다.


노트 2:

또 다른 중요한 점은에 대해 알아야 할 사항 anyall그 단락 실행, 그들은 결과를 알고 순간을 것입니다. 장점은 전체 iterable을 사용할 필요가 없다는 것입니다. 예를 들어

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

여기 에서 1과 9 내의 현재 숫자가 6의 배수 인 경우 (not (i % 6) for i in range(1, 10))리턴하는 생성기 표현식 True입니다.를 any반복하고 multiples_of_6만나면 6Truthy 값을 찾아 즉시 리턴 True하고 나머지는 multiples_of_6반복하지 않습니다. 그것은 우리가 우리가 인쇄 할 때 볼 무엇 list(multiples_of_6)의 결과를 7, 8하고 9.

이 훌륭한 것은 이 답변 에서 매우 영리하게 사용됩니다 .


이 기본 이해를 통해 코드를 살펴보면

any(x) and not all(x)

이는 값 중 적어도 하나가 Truthy이지만 모든 값이 아님을 확인합니다. 그것이 돌아 오는 이유 [False, False, False]입니다. 두 숫자가 동일하지 않은지 실제로 확인하려면

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

@ anyone : 빈 목록에 대해 True를 반환하는 경우를 제외하고 모두 사용해야하는 경우 허용되지 않습니다. 목록이 비어있는 경우 True를 제공하는 논리를 이해하지 못합니다 ... 의미 all ([]) == True
JavaSa

1
@JavaSa 목록이 비어 있는지 명시 적으로 확인할 수 있습니다. 나는 같은 bool(data) and all(...)것이 작동해야 한다고 생각 합니다.
thefourtheye

43

파이썬 anyall함수 는 어떻게 작동합니까?

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 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!

지름길을 염두에두면 진리표를 참조하지 않고도 작동 방식을 직관적으로 이해할 수 있다고 생각합니다.

증거 allany지름길 :

먼저 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;
}

1
참고 : 이것은 "모두"및 "존재"와 같은 수학 술어와 일치합니다. 혼란은 "모든"과 "대한 모든"다른 문맥에서 동의어 ... 것을 할 수 있습니다 en.wikipedia.org/wiki/List_of_logic_symbols
mcoolive

1
@ thanos.a에 있습니다 Python/bltinmodule.c-위에 추가했습니다.
Aaron Hall

14

나는 이것이 오래되었다는 것을 알고 있지만 코드에서 이러한 기능이 어떻게 보이는지 보여주는 것이 도움이 될 것이라고 생각했습니다. 이것은 실제로 텍스트 나 테이블 IMO보다 논리를 잘 보여줍니다. 실제로는 순수한 파이썬이 아닌 C로 구현되지만 이것과 동일합니다.

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

특히 빈 iterables의 결과는 특별한 경우가 아니라 자연스러운 결과라는 것을 알 수 있습니다. 단락 동작을 볼 수도 있습니다. 실제로 단락 이 없으면 더 많은 작업이 필요 합니다.

파이썬 제작자 인 Guido van Rossum이 처음으로 any()and를 추가 할 것을 제안all() 했을 때 , 그는 위의 코드 조각을 정확히 게시하여 설명했습니다.


10

귀하가 질문하는 코드는 here 주어진 내 대답에서 비롯 됩니다 . 여러 비트 배열을 비교하는 문제, 즉 1and 와의 수집 문제를 해결하기위한 것 0입니다.

any그리고 all당신이 값 "truthiness"에 의존 할 때 유용합니다 - 즉 부울 맥락에서 그 가치는. 1은 True0이고 False, 그 답은 활용 한 편의성입니다. 5는 또한 가능 True하므로 가능한 입력으로 혼합하면 잘됩니다. 작동하지 않습니다.

대신 다음과 같이 할 수 있습니다.

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

이전 답변의 미학이 부족합니다 ( 실제로 모양 마음에 들었습니다 any(x) and not all(x)).하지만 작업이 완료됩니다.


콜버트의 영향은 CS / CE에 도달하고있다 : en.wikipedia.org/wiki/Truthiness ? 퍼지 논리를 이야기하고 있습니까? : D
Geof Sawaya

OP가 True값이 다른시기를 요청
했으므로

@wombatonfire 하하 좋은 캐치. 7 살짜리 답변을 조정했습니다 :)
roippi

좋은 답변은 노화되지 않습니다 :) 세트로 멋진 접근.
wombatonfire

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


1

개념은 간단합니다.

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 

0
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 .
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.