Program Tip

파이썬에 첫 번째 (반복 가능한) 내장 함수가없는 이유는 무엇입니까?

programtip 2020. 11. 18. 09:40
반응형

파이썬에 첫 번째 (반복 가능한) 내장 함수가없는 이유는 무엇입니까?


first(iterable)파이썬 내장 함수에 any(iterable)and와 다소 유사한 이유가 있는지 궁금합니다 all(iterable)(어딘가에 stdlib 모듈에 들어갈 수 있지만에서 볼 수 없습니다 itertools). first불필요한 (그리고 잠재적으로 무한한 수의) 작업을 피할 수 있도록 단락 발생기 평가를 수행합니다.

def identity(item):
    return item

def first(iterable, predicate=identity):
    for item in iterable:
        if predicate(item):
            return item
    raise ValueError('No satisfactory value found')

이렇게하면 다음과 같은 것을 표현할 수 있습니다.

denominators = (2, 3, 4, 5)
lcd = first(i for i in itertools.count(1)
    if all(i % denominators == 0 for denominator in denominators))

list(generator)[0]생성기가 종료되지 않기 때문에이 경우 분명히 할 수 없습니다 .

또는 일치시킬 정규 표현식이 여러 개있는 경우 (모두 동일한 groupdict인터페이스를 가질 때 유용합니다 ) :

match = first(regex.match(big_text) for regex in regexes)

list(generator)[0]포지티브 매치 를 피하고 단락 시킴으로써 불필요한 처리를 많이 줄일 수 있습니다.


반복기가있는 경우 해당 next메서드를 호출 할 수 있습니다 . 다음과 같은 것 :

In [3]: (5*x for x in xrange(2,4)).next()
Out[3]: 10

이를 수행하는 "first"라는 Pypi 패키지 가 있습니다 .

>>> from first import first
>>> first([0, None, False, [], (), 42])
42

다음은 첫 번째 홀수를 반환하는 데 사용하는 방법입니다. 예를 들면 다음과 같습니다.

>> first([2, 14, 7, 41, 53], key=lambda x: x % 2 == 1)
7

참 여부에 관계없이 반복기에서 첫 번째 요소를 반환하려면 다음을 수행하십시오.

>>> first([0, None, False, [], (), 42], key=lambda x: True)
0

매우 작은 패키지입니다.이 함수 만 포함하고 종속성이 없으며 Python 2 및 3에서 작동합니다. 단일 파일이므로 사용하기 위해 설치할 필요도 없습니다.

사실, 여기에 거의 전체 소스 코드가 있습니다 (버전 2.0.1부터, Hynek Schlawack이 MIT 라이센스로 배포) :

def first(iterable, default=None, key=None):
    if key is None:
        for el in iterable:
            if el:
                return el
    else:
        for el in iterable:
            if key(el):
                return el
    return default

내가 물어 비슷한 질문을 (지금으로이 질문의 중복으로 표시되었다)는 최근. 내 관심사는 또한 발전기의 첫 번째 진정한 가치를 찾는 문제를 해결하기 위해서만 내장 기능을 사용하고 싶다는 것 입니다. 내 자신의 해결책은 다음과 같습니다.

x = next((v for v in (f(x) for x in a) if v), False)

첫 번째 정규식 일치 (첫 번째 일치 패턴이 아님)를 찾는 예는 다음과 같습니다.

patterns = [ r'\d+', r'\s+', r'\w+', r'.*' ]
text = 'abc'
firstMatch = next(
  (match for match in
    (re.match(pattern, text) for pattern in patterns)
   if match),
  False)

조건자를 두 번 평가하지 않으며 (패턴 만 반환 된 경우 수행해야하는 것처럼) 이해에서 지역인과 같은 해킹을 사용하지 않습니다.

그러나 논리가 하나만 사용하도록 지시하는 두 개의 생성기가 중첩되어 있습니다. 따라서 더 나은 솔루션이 좋을 것입니다.


There is a "slice" iterator in itertools. It emulates the slice operations that we're familiar with in python. What you're looking for is something similar to this:

myList = [0,1,2,3,4,5]
firstValue = myList[:1]

The equivalent using itertools for iterators:

from itertools import islice
def MyGenFunc():
    for i in range(5):
        yield i

mygen = MyGenFunc()
firstValue = islice(mygen, 0, 1)
print firstValue 

There's some ambiguity in your question. Your definition of first and the regex example imply that there is a boolean test. But the denominators example explicitly has an if clause; so it's only a coincidence that each integer happens to be true.

It looks like the combination of next and itertools.ifilter will give you what you want.

match = next(itertools.ifilter(None, (regex.match(big_text) for regex in regexes)))

Haskell makes use of what you just described, as the function take (or as the partial function take 1, technically). Python Cookbook has generator-wrappers written that perform the same functionality as take, takeWhile, and drop in Haskell.

But as to why that's not a built-in, your guess is as good as mine.

참고URL : https://stackoverflow.com/questions/1077307/why-is-there-no-firstiterable-built-in-function-in-python

반응형