[python] 무한 생성기에 대한 표현이 있습니까?

무한한 요소를 생성 할 수있는 간단한 생성기 표현식이 있습니까?

이것은 순전히 이론적 인 질문입니다. 여기에 “실용적인”대답이 필요 없습니다. 🙂


예를 들어, 유한 제너레이터를 만드는 것은 쉽습니다.

my_gen = (0 for i in xrange(42))

그러나 무한한 것을 만들려면 내 네임 스페이스를 가짜 함수로 “오염”시켜야합니다.

def _my_gen():
    while True:
        yield 0
my_gen = _my_gen()

별도의 파일에서 작업하고 import나중에 -ing하는 것은 중요하지 않습니다.


나는 또한 그것이 itertools.repeat정확히 이것을 한다는 것을 압니다 . 그것없이 한 줄짜리 솔루션이 있는지 궁금합니다.



답변

for x in iter(int, 1): pass
  • 2 인수 iter= 0 인수 호출 가능 + 센티넬 값
  • int() 항상 반환 0

따라서 iter(int, 1)무한 반복자입니다. 이 특정 테마에는 분명히 수많은 변형이 있습니다 (특히 lambda믹스에 추가 한 경우). 특정 메모의 한 가지 변형은 iter(f, object()), 새로 생성 된 객체를 센티넬 값으로 사용하면 첫 번째 인수로 사용되는 콜 러블에 관계없이 거의 무한 반복자를 보장하기 때문입니다.


답변

itertools 세 가지 무한 생성기를 제공합니다.

나는 표준 라이브러리의 다른 어떤 것도 모른다.


한 줄짜리를 요청했기 때문에 :

__import__("itertools").count()


답변

iter ()의 센티넬과 항상 다른 상수를 반환하는 콜 러블을 반복 할 수 있습니다.

g1=iter(lambda:0, 1)


답변

OS는 무한 생성기로 사용할 수있는 무언가를 제공 할 수 있습니다. 예 : Linux에서

for i in (0 for x in open('/dev/urandom')):
    print i

분명히 이것은 효율적이지 않습니다.

for i in __import__('itertools').repeat(0)
    print i


답변

클래스 / 함수 / 생성자로 정의 된 다른 무한 반복기를 내부적으로 사용하지 않는 없음 (-expression이 아님,을 사용하는 함수 yield). 생성기 표현식은 항상 반복 가능한 anoter에서 가져오고 항목을 필터링하고 매핑하는 것 외에는 아무것도하지 않습니다. 만에 무한한 것과 유한 한 항목에서 갈 수 없어 map하고 filter, 당신이 필요로 while(또는 for우리는 사용 할 수 없습니다 정확히 무엇 인 종료되지 않는 for및 유한 반복자).

퀴즈 : PEP 3142 는 표면적으로 비슷하지만 자세히 살펴보면 여전히 for조항이 필요한 것 같습니다 (그래서 아니오 (0 while True)). 즉, itertools.takewhile.


답변

매우 추하고 미친 짓이지만 (매우 웃기지 만) 몇 가지 트릭을 사용하여 표현식에서 고유 한 반복기를 만들 수 있습니다 (필요에 따라 네임 스페이스를 “오염”하지 않고).

{ print("Hello world") for _ in
    (lambda o: setattr(o, '__iter__', lambda x:x)
            or setattr(o, '__next__', lambda x:True)
            or o)
    (type("EvilIterator", (object,), {}))() } 


답변

예를 들어 다음과 같은 데코레이터를 사용할 수 있습니다.

def generator(first):
    def wrap(func):
        def seq():
            x = first
            while True:
                yield x
                x = func(x)
        return seq
    return wrap

사용법 (1) :

@generator(0)
def blah(x):
    return x + 1

for i in blah():
    print i

사용법 (2)

for i in generator(0)(lambda x: x + 1)():
    print i

나는 그 추악한 것을 제거하는 것이 더 개선 될 수 있다고 생각한다 (). 그러나 만들 수있는 시퀀스의 복잡성에 따라 다릅니다. 일반적으로 시퀀스를 함수를 사용하여 표현할 수 있다면 생성자의 모든 복잡성과 구문 설탕이 데코레이터 또는 데코레이터와 같은 함수 안에 숨겨 질 수 있습니다.