私たちはすべてを繰り返します

画像

自分の経験から理解できた限り、別のプログラミング言語からPythonに切り替えると、ループに対する特定のアプローチに慣れることが難しい場合があります。 たとえば、他の言語とはまったく異なる方法で動作するについても同じようにします。 私は、最初は実現するのが難しかったこと、さらにはコードでイテレータを使用することは難しかったことについて話す自由を取ります。 事は実際には非常に便利です、あなたはそれを正しく使用できるようにする必要があります! ;)



APD :関数型プログラミングのトピックは今日、これまで以上に人気があることに気づきました:)このような興味深いトピックの開示をしてくれたuj2に感謝します。



イテレータは、コンテナからのデータへの順次アクセスを表す特別なオブジェクトです。 要求時に中間データが必要に応じて発行されるため、実際にはメモリが無駄にならないという事実が重要な役割を果たします。実際には、初期データと最終結果のみがメモリに残り、ディスク上のファイルを使用して読み書きすることもできます。



イテレータは、シーケンスで使用すると便利です。 イテレータインターフェイスをサポートするオブジェクトにはnext()メソッドがあり、計算の次のステップに進むことができます。 オブジェクト(リストなど)のイテレータを取得するには、 iter()関数を適用する必要があります。 ちなみに、既に述べたforループも追加のダンスなしでイテレータを使用します-すべてが自動的に行われます。 複雑なデータセットを処理するには、標準のitertoolsモジュールを接続できます。



最も単純なイテレータを手動で作成します。

testIt = iter([1, 2, 3, 4, 5])

print [x for x in testIt]






もちろん、これはforループの最も単純な使用方法であり、少し異なる方法で記述されています。

「そして、何が新しいの?」とあなたは尋ねます。 はい、原則として、何もありません。処理シーケンスの構造の少し深いところにあります。 しかし、今、それはあなたのためです: iter()関数は、イテレータを非常に簡単に表すデータ構造だけでなく、2つの完全に異なる引数を取ることができます:引数なしの関数と、反復が停止する停止値。 例:

def getSimple(state=[]):

if len(state) < 4:

state.append(" ")

return " "



testIt2 = iter(getSimple, None)

print [x for x in testIt2]






この例は、Pythonでは、関数からの値の明示的な戻り値がない場合、値Noneが返されるという事実に基づいています。



次に、イテレーターに基づいた作業を行ういくつかの関数を考えます。



列挙()

データ構造要素(別の反復子を含む)に番号を付けるために設計されています。 タプルのリストを返します。各リストの最初の要素は(ゼロから始まる)数値で、2番目の要素は元の反復子の要素です。 例:

>>> print [x for x in enumerate("abcd")]

[(0, 'a'), (1, 'b'), (2, 'c'), (3, 'd')]






ソート済み()

ソートイテレーター:

>>> sorted('avdsdf')

['a', 'd', 'd', 'f', 's', 'v']






itertools.chain()

2つの異なるイテレータを1つに結合できるイテレータ。 例:

from itertools import chain

it1 = iter([1,2,3])

it2 = iter([8,9,0])

for i in chain(it1, it2):

print i,






「1 2 3 8 9 0」になります。



itertools.count()

次で始まる無限の数を生成する反復子:

for i in itertools.count(1):

print i,

if i > 100:

break






結果:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72

73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 85 86 87 88 89 90

96 97 98 99 100 101



itertools.cycle()

指定されたシーケンスを無限に繰り返します:

tango = [1, 2, 3]

for i in itertools.cycle(tango):

print i,






結果:

1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3 1 ..



また、このモジュールには類似物map()starmap()filter()およびzip()があり 、もちろんitertools.imap()itertools.starmap()itertools.ifilter()およびitertools.izip( ) それらの利点は、「通常の」対応物とは異なり、消費するメモリがはるかに少ないことです。 いくつかのフィルターもあります: itertools.takewhile()およびitertools.dropwhile()

for i in takewhile(lambda x: x > 0, [1, -2, 3, -3]):

print i,

for i in dropwhile(lambda x: x > 0, [1, -2, 3, -3]):

print i,






結果:

1

-2 3 -3



事実は、 takewhile()は条件が真になるまで値を返し、イテレータから残りの値さえも取りません(取りませんが、すべてを最後まで使い尽くしません!)。 また、逆に、 dropwhile()は条件が満たされるまで何も返しませんが、残りのないすべてを返します。



最後に、私たち自身のイテレータを書いてみましょう(ベンダーの有名なフレーズを書き終えたところです)!



class Fibonacci:

""" N"""

def __init__(self, N):

self.n, self.a, self.b, self.max = 0, 0, 1, N

def __iter__(self):

# : next()

return self

def next(self):

if self.n < self.max:

a, self.n, self.a, self.b = self.a, self.n+1, self.b, self.a+self.b

return a

else:

raise StopIteration

# :

for i in Fibonacci(100):

print i,






それは実際、全体の基本理論です。 もっと微妙なことを学びたいなら、特別な文献を読んでください。 コメントがあれば-私は聞いてうれしいです:)



この記事では、Roman Arvievich Susiによる講義「関数型プログラミングの要素」の資料を使用しています。



All Articles