콜백을 사용하는 Python의 any() 함수
-
19-09-2019 - |
문제
Python 표준 라이브러리는 다음을 정의합니다. any()
그 기능
iterable의 요소 중 하나라도 true이면 True를 반환합니다.iterable이 비어 있으면 False를 반환합니다.
요소가 다음과 같이 평가되는 경우에만 확인합니다. True
.내가 원하는 것은 다음과 같이 요소가 청구서에 맞는지 알려주는 콜백을 지정하는 것입니다.
any([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0)
해결책
어때요 :
>>> any(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
True
또한 함께 작동합니다 all()
물론이야:
>>> all(isinstance(e, int) and e > 0 for e in [1,2,'joe'])
False
다른 팁
어느 조건이 참을 때 함수는 true를 반환합니다.
>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 1])
True # Returns True because 1 is greater than 0.
>>> any(isinstance(e, int) and e > 0 for e in [0 ,0, 0])
False # Returns False because not a single condition is True.
사실, 개념 어느 기능은 LISP에서 가져 오거나 기능 프로그래밍 방식에서 말할 수 있습니다. 그것과 반대되는 또 다른 함수가 있습니다. 모두
>>> all(isinstance(e, int) and e > 0 for e in [1, 33, 22])
True # Returns True when all the condition satisfies.
>>> all(isinstance(e, int) and e > 0 for e in [1, 0, 1])
False # Returns False when a single condition fails.
이 두 기능은 제대로 사용될 때 정말 시원합니다.
"발전기 표현"을 사용해야합니다. 즉, 반복자를 소비하고 필터 및 표현식을 한 줄에 적용 할 수있는 언어 구조물입니다.
예를 들어 (i ** 2 for i in xrange(10))
처음 10 자연 숫자의 제곱을위한 발전기 (0 ~ 9)
또한 "경우"조항이 "for"절에서 Itens를 필터링하도록 허용하므로 예를 들어 사용할 수 있습니다.
any (e for e in [1, 2, 'joe'] if isinstance(e, int) and e > 0)
Antoine P의 답변에 대한 약간의 개선
>>> any(type(e) is int for e in [1,2,'joe'])
True
을 위한 all()
>>> all(type(e) is int for e in [1,2,'joe'])
False
다른 사람들은 좋은 피토닉 답변을 주었지만 (대부분의 경우 받아 들여진 답을 사용합니다), 나는 당신이 정말로 선호하는 경우 자신의 유틸리티 기능을 직접 수행하는 것이 얼마나 쉬운 지 지적하고 싶었습니다.
def any_lambda(iterable, function):
return any(function(i) for i in iterable)
In [1]: any_lambda([1, 2, 'joe'], lambda e: isinstance(e, int) and e > 0
Out[1]: True
In [2]: any_lambda([-1, '2', 'joe'], lambda e: isinstance(e, int) and e > 0)
Out[2]: False
그래도 map () 및 filter ()와 같은 기존 내장 함수와 더 밀접하게 일치하기 때문에 최소한 기능 매개 변수로 먼저 정의 할 것이라고 생각합니다.
def any_lambda(function, iterable):
return any(function(i) for i in iterable)
필터는 작동 할 수 있으며 일치하는 요소를 반환합니다.
>>> filter(lambda e: isinstance(e, int) and e > 0, [1,2,'joe'])
[1, 2]
조합을 사용할 수 있습니다 any
그리고 map
당신이 정말로 당신의 람다 표기법을 그렇게 유지하고 싶다면 :
any(map(lambda e: isinstance(e, int) and e > 0, [1, 2, 'joe']))
그러나 전체 목록을 두 번 구축하지 않기 때문에 발전기 표현식을 사용하는 것이 좋습니다.
만약 너라면 정말 any()에 람다를 인라인하려면 다음과 같이 하면 됩니다.
>>> any((lambda: isinstance(e, int))() for e in [1,2,'joe'])
True
>>> any((lambda: isinstance(e, int))() for e in ['joe'])
False
이름이 지정되지 않은 람다를 마무리하고 다음을 추가하여 각 패스에서 호출되도록 하면 됩니다. ()
여기서의 장점은 첫 번째 int에 도달할 때 평가를 단락시키는 이점을 여전히 활용할 수 있다는 것입니다.