無限ジェネレーターの式はありますか?


119

無限要素を生成できる単純なジェネレータ式はありますか?

これは純粋に理論的な質問です。ここに「実用的な」答えは必要ありません:)


たとえば、有限ジェネレータを作成するのは簡単です。

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

ただし、無限のものを作成するには、偽の関数で名前空間を「汚染」する必要があります。

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

別のファイルで処理を行い、import後で-ing することは考慮されません。


私はそれitertools.repeatがまさにこれを行うことも知っています。それなしでワンライナーソリューションがあるかどうか私は興味があります。


9
名前空間を実際に汚染する必要はありmy_genませんmy_gen = my_gen()。関数に名前を付けてから実行してください。
6502

2
del _my_gen2つを混同したくない場合にも使用できます
John La Rooy

回答:


133
for x in iter(int, 1): pass
  • 2つの引数iter=ゼロ引数の呼び出し可能+センチネル値
  • int() 常に戻る 0

したがって、iter(int, 1)無限反復子です。この特定のテーマには、明らかに膨大な数のバリエーションがあります(特にlambda、ミックスに追加すると)。iter(f, object())新たに作成されたオブジェクトをセンチネル値として使用すると、最初の引数として使用される呼び出し可能オブジェクトに関係なく、無限の反復子がほぼ保証されるため、特定の注意の1つの変形があります。


3
私たちが何度も忘れiterているプロパティで使用する非常に興味深い方法int
Senthil Kumaran、2011

3
あなたは、シミュレートするために、この魔法のレシピを使用することができますitertools.countcount = lambda start=0, step=1: (start + i*step for i, _ in enumerate(iter(int, 1)))
Coffee_Table

1
ここで何が行われているのかを説明するだけiterです。2つの引数を指定して-functionを呼び出すと、通常とは少し動作が異なります iter(callable, sentinel) -> iterator。引数1 は、の値が返されるまでcallable、反復子の反復ごとに呼び出されます。しかし、常に返します、我々は呼び出すことができる効果のこの意志は、無限のリストを生成1.永遠に、決して届かさんsentinelint()0int()0
Olsgaard

217

itertools 3つの無限ジェネレーターを提供します。

私は標準ライブラリに他のものを知りません。


ワンライナーを求めたので:

__import__("itertools").count()

18
Re:repeat(x、times =∞)- 誰も不思議に思っている人のためのシンボルはありません-引数を省略すると繰り返し実行されます
Mr_and_Mrs_D

(ncoghlanの回答がOPの質問に直接対処する一方で)これはより一般的に適用できるため、賛成です。
Huw Walters、2018

これはiter(int, 1)呪文よりもはるかに読みやすいです。残念ながらitertoolsendlessly()これを唯一の目的とするメソッドはありません。itertools.count()どちらもそれほど読みやすいわけではありません。
BallpointBen 2018

19

iter()の標識とは常に異なる定数を返す呼び出し可能オブジェクトを反復できます

g1=iter(lambda:0, 1)

8
私はこれを愛することも憎むことも...私はほんの少しのキャラクターで私が望むことを達成するのが好きですが、誰もそれを見て、何をするつもりなのかを知ることは嫌いです。
ArtOfWarfare 2017年

1
iter(ここでは追加のセンチネルを使用)の構文とlambda(ここでは渡されたパラメーターを使用せずに)の構文を知っているreturn 0ので、嫌いなのはその不可解な場所だけg1です。
SławomirLenart

@SławomirLenart男性は決してそれを取得しません。恥ずかしそうに小さかったので1g潮吹きました。
user237419

8

お使いのOSは、無限ジェネレーターとして使用できるものを提供している場合があります。例:Linux

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

明らかにこれはそれほど効率的ではありません

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

11
/ dev / urandomソリューションは\n、時々現れるsに依存します...不正です!:)
hugomg

5

クラス/関数/ジェネレーターとして定義された別の無限イテレーターを内部で使用しないものはありません(式ではなく、を使用した関数yield)。ジェネレーター式は常にイテラブルアノテーターから描画され、そのアイテムのフィルタリングとマッピングのみを行います。mapand だけではfilter、有限のアイテムから無限のアイテムに移動することはできませんwhile(または、for終了しないa が必要です。これは、forと、有限イテレータ)。

雑学:PEP 3142は表面的には似ていますが、よく調べてみると、まだfor条項が必要であるように見え(0 while True)ます(そのため、お客様には不要です)。つまり、のショートカットのみを提供しますitertools.takewhile


私が疑ったように...乱用するためにすぐに利用できる無限のジェネレータがないことを確信できますか?(残念ながら、xrange(0,1、-1)は機能しません...)
hugomg

2
@missingno:from itertools import repeat, count, cycleおそらくほとんどの人にとって「すぐに利用できる」と見なされます。
ncoghlan 2011

1
おっと、私は2引数について忘れていましたiter。無限反復子は実際には組み込みとして利用できます-私の答えを見てください:)
ncoghlan

5

かなり醜く、クレイジーです(ただし、非常に面白いです)、いくつかのトリックを使用して、式から独自のイテレータを構築できます(必要に応じて名前空間を「汚染」することはありません)。

{ 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,), {}))() } 

あなたは明らかにLISPを愛しています
Faissaloo

1
:@Faissaloo確かに...あなたは、私が書いた古いページで、まだ多くの非常識な表現かもしれませんbaruchel.github.io/python/2018/06/20/...
トーマスBaruchel

2

たとえば、次のようなデコレータを使用できます。

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

これらの醜いものを取り除くにはさらに改善できると思います()。ただし、作成できるシーケンスの複雑さによって異なります。一般的に言えば、シーケンスを関数を使用して表現できる場合、ジェネレーターのすべての複雑さと構文上の砂糖をデコレーターまたはデコレーターのような関数の中に隠すことができます。


9
OPがonelinerを要求し、トリプルネストdefとクロージャーを備えた10行のデコレーターを提示しますか?;)

2
@delnanまあ、デコレータを一度定義すると、1つのライナーを持つことができますね。私が理解しているように、目的は、追加の各無限ジェネレーターを1行で実装することです。そして、これがここに提示されているものです。あなたが持つことができる(2^x)、あなたが持つことができます(x)。あなたがそれを少し改善するかもしれないならば、おそらくフィボナッチなど
julx

私の質問には答えませんが、どうしてこれらのふわふわしたクロージャーをすべて愛せないのでしょうか?ところで、seqコードをwrap
削除
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.