program tip

파이썬 빈 생성기 함수

radiobox 2020. 9. 23. 07:29
반응형

파이썬 빈 생성기 함수


파이썬에서는 다음과 같이 yield 키워드를 함수 본문에 넣어 반복자 함수를 쉽게 정의 할 수 있습니다.

def gen():
    for i in range(100):
        yield i

값을 생성하지 않는 (0 값 생성) 생성기 함수를 어떻게 정의 할 수 있습니까? 다음 코드는 작동하지 않습니다. 왜냐하면 파이썬은 그것이 일반 함수가 아닌 생성기인지 알 수 없기 때문입니다.

def empty():
    pass

나는 다음과 같이 할 수 있었다.

def empty():
    if False:
        yield None

그러나 그것은 매우 추한 것입니다. 빈 반복기 함수를 실현하는 좋은 방법이 있습니까?


return생성기에서 한 번만 사용할 수 있습니다 . 아무것도 산출하지 않고 반복을 중지하므로 함수가 범위를 벗어나도록하는 것에 대한 명시적인 대안을 제공합니다. 따라서 yield함수를 제너레이터로 바꾸려면을 사용 하십시오. 그러나 return어떤 것을 산출하기 전에 제너레이터를 종료하려면 먼저 사용하십시오.

>>> def f():
...     return
...     yield
... 
>>> list(f())
[]

나는 그것이 당신이 가진 것보다 훨씬 낫다는 것을 확신하지 못합니다-단지 no-op if문을 no-op 문으로 대체합니다 yield. 그러나 그것은 더 관용적입니다. 그냥 사용 yield하는 것은 작동하지 않습니다.

>>> def f():
...     yield
... 
>>> list(f())
[None]

왜 그냥 사용하지 iter(())않습니까?

이 질문은 빈 생성기 함수 에 대해 구체적으로 묻습니다 . 따라서 일반적으로 빈 반복기를 만드는 가장 좋은 방법에 대한 질문 이라기보다는 Python 구문의 내부 일관성에 대한 질문으로 간주합니다.

질문이 실제로 빈 반복기를 만드는 가장 좋은 방법에 관한 것이라면iter(()) 대신 사용 하는 것에 대해 Zectbumo동의 할 수 있습니다 . 그러나 iter(())함수를 반환하지 않는 것을 관찰하는 것이 중요 합니다! 빈 이터 러블을 직접 반환합니다. 이터 러블 반환 하는 콜 러블을 기대하는 API로 작업한다고 가정합니다 . 다음과 같이해야합니다.

def empty():
    return iter(())

( 이 답변의 첫 번째 올바른 버전을 제공 한 크레딧은 Unutbu가야합니다 .)

이제 위의 내용이 더 명확해질 수 있지만 덜 명확 할 상황을 상상할 수 있습니다. (기여 된) 생성기 함수 정의의 긴 목록의 다음 예를 고려하십시오.

def zeros():
    while True:
        yield 0

def ones():
    while True:
        yield 1

...

긴 목록 끝에 다음과 같이 a가 yield있는 것을보고 싶습니다 .

def empty():
    return
    yield

or, in Python 3.3 and above (as suggested by DSM), this:

def empty():
    yield from ()

The presence of the yield keyword makes it clear at the briefest glance that this is just another generator function, exactly like all the others. It takes a bit more time to see that the iter(()) version is doing the same thing.

It's a subtle difference, but I honestly think the yield-based functions are more readable and maintainable.


iter(())

You don't require a generator. C'mon guys!


Python 3.3 (because I'm on a yield from kick, and because @senderle stole my first thought):

>>> def f():
...     yield from ()
... 
>>> list(f())
[]

But I have to admit, I'm having a hard time coming up with a use case for this for which iter([]) or (x)range(0) wouldn't work equally well.


Another option is:

(_ for _ in ())

I prefer the following:

def foo():
  raise StopIteration()
  yield

The "yield" turns it into a generator while Exception means None isn't included in the result (purely empty result).


Must it be a generator function? If not, how about

def f():
    return iter([])

The "standard" way to make an empty iterator appears to be iter([]). I suggested to make [] the default argument to iter(); this was rejected with good arguments, see http://bugs.python.org/issue25215 - Jurjen


generator = (item for item in [])

For those of you that actually need a function and actually need a generator

empty = lambda: (_ for _ in ())

참고URL : https://stackoverflow.com/questions/13243766/python-empty-generator-function

반응형