回答:
イテレーションは、何かの各アイテムを次々と取得するための一般的な用語です。明示的または暗黙的なループを使用して、アイテムのグループ、つまり反復を処理するとき。
Pythonでは、反復可能オブジェクトと反復子には特定の意味があります。
反復可能であるオブジェクトで__iter__
返すメソッド反復子を、または定義する__getitem__
ゼロから始まるシーケンシャルインデックスを取る(および提起することができない方法IndexError
インデックスがもはや有効である場合に)。つまり、イテラブルは、イテレーターを取得できるオブジェクトです。
反復子が持つオブジェクトであるnext
(パイソン2)または__next__
(Pythonの3)の方法。
Pythonでfor
ループ、or map
、リスト内包などを使用すると、next
メソッドが自動的に呼び出され、イテレータから各項目が取得されるため、反復プロセスが実行されます。
学習を始めるのに適した場所は、チュートリアルのイテレータセクションと標準タイプのページのイテレータタイプセクションです。基本を理解したら、関数型プログラミングHOWTOのイテレータセクションを試してください。
__len__
必ず反復に関連付けられるのですか?何かの長さを知ることは、それを反復するのにどのように役立ちますか?
__getitem__
。
{'a': 'hi', 'b': 'bye'}
2の長さを有するが、0、1、または2によってインデックス付けすることができない
__iter__
方法があります。jlhは、特に「__getitem__
0から始まる順次インデックスを取得できるメソッド」を定義しているため、反復可能なオブジェクトを参照していると思います。
Pythonクラスを教える際に使用する説明は次のとおりです。
ITERABLEは次のとおりです。
for x in iterable: ...
またはiter()
ITERATORを返します: iter(obj)
または__iter__
新しいITERATORを返すことを定義するオブジェクト、または__getitem__
インデックス付きルックアップに適したメソッドがある場合があります。ITERATORはオブジェクトです。
__next__
方法で:
StopIteration
__iter__
を返すメソッドがあることを意味しますself
)。ノート:
__next__
Python 3 のメソッドはPython 2で記述さnext
れており、next()
は、渡されたオブジェクトでそのメソッドを呼び出します。例えば:
>>> s = 'cat' # s is an ITERABLE
# s is a str object that is immutable
# s has no state
# s has a __getitem__() method
>>> t = iter(s) # t is an ITERATOR
# t has state (it starts by pointing at the "c"
# t has a next() method and an __iter__() method
>>> next(t) # the next() function returns the next value and advances the state
'c'
>>> next(t) # the next() function returns the next value and advances
'a'
>>> next(t) # the next() function returns the next value and advances
't'
>>> next(t) # next() raises StopIteration to signal that iteration is complete
Traceback (most recent call last):
...
StopIteration
>>> iter(t) is t # the iterator is self-iterable
for
ループに関するものであり、1番目の弾丸は「ループオーバー」に関するものであるため、1 番目の弾丸は2番目の弾丸と重複しているように見えます。これらに対処できますか?
iter()
」「あなたに渡すことができるものとしてiter()
、」
上記の答えは素晴らしいですが、私が見たことのほとんどとして、私のような人々のために区別を十分に強調しないでください。
また、人々は__foo__()
以前に「Xはメソッドを持つオブジェクト」のような定義を置くことによって「あまりにもPythonic」になる傾向があります。そのような定義は正しいです。それらはダックタイピングの哲学に基づいていますが、メソッドに焦点を当てるのは、その単純さで概念を理解しようとするときに中間になる傾向があります。
だから私は私のバージョンを追加します。
自然言語で
Pythonでは、
iterableは、まあ、反復可能であるオブジェクトです。つまり、for
ループなどで繰り返し使用できることを意味します。どうやって?イテレータを使用する。以下に説明します。
... イテレータは、実際に反復を行う方法を定義するオブジェクトです。具体的には、次の要素は何ですか。それがnext()
メソッドを持たなければならない理由
です。
イテレータ自体も反復可能ですが、その項目が以前のの呼び出しによって消費されたかどうかに関係なく、__iter__()
メソッドが同じオブジェクト(self
)を返す点が異なりますnext()
。
では、Pythonインタープリターはfor x in obj:
ステートメントを見て、どう思いますか?
見て、
for
ループ。イテレータの仕事のように見えます...取得しましょう。...このobj
男がいるので、彼に聞いてみましょう。「さん
obj
、イテレータはありますか?」(...呼び出しiter(obj)
、呼び出しobj.__iter__()
、光沢のある新しいイテレータを楽しそうに渡し_i
ます)OK、それは簡単でした...それでは反復を始めましょう。(
x = _i.next()
...x = _i.next()
...)
Mr. obj
がこのテストに成功したので(特定のメソッドが有効なイテレータを返すことで)、形容詞で彼に報酬を与えますobj
。これで、彼を「反復可能なMr. 」と呼ぶことができます。
ただし、単純なケースでは、通常、イテレータとイテラブルを個別に使用するメリットはありません。したがって、オブジェクトを1つだけ定義します。これは、独自のイテレータでもあります。(Pythonは、_i
配布されたものobj
がそれほど光沢があるわけではなく、obj
それ自体が本当に気にしません。)
これが、私が見たほとんどの例(および私を何度も混乱させていたもの)で、次のことを確認できる理由です。
class IterableExample(object):
def __iter__(self):
return self
def next(self):
pass
の代わりに
class Iterator(object):
def next(self):
pass
class Iterable(object):
def __iter__(self):
return Iterator()
ただし、イテレータをイテラブルから分離することでメリットが得られる場合もあります。たとえば、1行のアイテムで「カーソル」を増やしたい場合などです。たとえば、「現在の」要素と「今後の」要素を操作する場合は、両方に別々のイテレータを使用できます。または、巨大なリストからプルする複数のスレッド:各スレッドは、すべてのアイテムをトラバースする独自のイテレータを持つことができます。参照してください@レイモンドさんと@ glglglの上記の答え。
あなたが何ができるか想像してみてください:
class SmartIterableExample(object):
def create_iterator(self):
# An amazingly powerful yet simple way to create arbitrary
# iterator, utilizing object state (or not, if you are fan
# of functional), magic and nuclear waste--no kittens hurt.
pass # don't forget to add the next() method
def __iter__(self):
return self.create_iterator()
ノート:
もう一度繰り返します。反復子は反復可能ではありません。イテレータをfor
ループの「ソース」として使用することはできません。どのようなfor
ループは、主に必要なのはある__iter__()
(とリターンの何かということnext()
)。
もちろん、for
これが唯一の反復ループではないため、上記は他のいくつかの構成にも適用されます(while
...)。
イテレータnext()
はStopIterationをスローして反復を停止できます。ただし、必ずしも繰り返す必要はありません。
上記の「思考プロセス」では、_i
実際には存在しません。私はその名前を作りました。
Python 3.xに小さな変更があります。next()
メソッド(組み込みではない)を呼び出さなければなりません__next__()
。はい、それはずっとそうだったはずです。
次のように考えることもできます:iterableにはデータがあり、イテレータは次のアイテムをプルします
免責事項:私はPythonインタープリターの開発者ではないので、インタープリターが何を「考える」のか本当にわかりません。上記の黙想は、Python初心者の他の説明、実験、および実際の経験からトピックをどのように理解するかを示すデモにすぎません。
for
ループにイテレーターが必要だと言っていると思いました(「見て、forループ。イテレーターの仕事のように見えます...始めましょう」)。しかし、最後のメモで「イテレータはfor
ループ内のソースとして使用できない」と言っています...?
pass
これらのnext
定義のコードだけを入れるのですか?次は何かを返さなければならないので、誰かが次のものを取得する方法を実装しなければならないことを単にあなたが意味すると仮定します。
for
ループの「ソース」として使用できません。私はあなたの答えの要点を理解し、そうでなければそれが好きですが、これを修正することには利益があると思います。
反復可能オブジェクトは、__iter__()
メソッドを持つオブジェクトです。list()
sやtuple()
s などのように、数回反復する可能性があります。
イテレータは、反復するオブジェクトです。__iter__()
メソッドによって返され、独自の__iter__()
メソッドを介して自身を返し、メソッドを持っていnext()
ます(__next__()
3.xの場合)。
反復は、このnext()
応答を呼び出すプロセスです。__next__()
それが上がるまでStopIteration
。
例:
>>> a = [1, 2, 3] # iterable
>>> b1 = iter(a) # iterator 1
>>> b2 = iter(a) # iterator 2, independent of b1
>>> next(b1)
1
>>> next(b1)
2
>>> next(b2) # start over, as it is the first call to b2
1
>>> next(b1)
3
>>> next(b1)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> b1 = iter(a) # new one, start over
>>> next(b1)
1
Iterable
。確かに私はそれを独立させないで有効なものにすることもできます。
Iterator
あり、常にIterable
、そしてそれ自体であるIterator
ので、の2つの呼び出しは、iter()
必ずしも2つの独立したを与えるわけではありませんIterator
。
これが私のチートシートです:
sequence
+
|
v
def __getitem__(self, index: int):
+ ...
| raise IndexError
|
|
| def __iter__(self):
| + ...
| | return <iterator>
| |
| |
+--> or <-----+ def __next__(self):
+ | + ...
| | | raise StopIteration
v | |
iterable | |
+ | |
| | v
| +----> and +-------> iterator
| ^
v |
iter(<iterable>) +----------------------+
|
def generator(): |
+ yield 1 |
| generator_expression +-+
| |
+-> generator() +-> generator_iterator +-+
クイズ:どうですか...
__iter__()
メソッドはジェネレータとして実装できますか?__next__
メソッドを持つイテラブルは必ずしもイテレータではありませんか?答え:
__iter__
メソッドが必要です。持つ__iter__
ことは反復可能であるのに十分です。したがって、すべての反復子は反復可能です。場合は__iter__
、それが(イテレータを返すべきであると呼ばれreturn <iterator>
、上記の図に)。ジェネレータを呼び出すと、イテレータの一種であるジェネレータイテレータが返されます。
class Iterable1:
def __iter__(self):
# a method (which is a function defined inside a class body)
# calling iter() converts iterable (tuple) to iterator
return iter((1,2,3))
class Iterable2:
def __iter__(self):
# a generator
for i in (1, 2, 3):
yield i
class Iterable3:
def __iter__(self):
# with PEP 380 syntax
yield from (1, 2, 3)
# passes
assert list(Iterable1()) == list(Iterable2()) == list(Iterable3()) == [1, 2, 3]
次に例を示します。
class MyIterable:
def __init__(self):
self.n = 0
def __getitem__(self, index: int):
return (1, 2, 3)[index]
def __next__(self):
n = self.n = self.n + 1
if n > 3:
raise StopIteration
return n
# if you can iter it without raising a TypeError, then it's an iterable.
iter(MyIterable())
# but obviously `MyIterable()` is not an iterator since it does not have
# an `__iter__` method.
from collections.abc import Iterator
assert isinstance(MyIterable(), Iterator) # AssertionError
__iter__
メソッドを持つため、イテラブルになります。この回答を編集して、2番目と3番目のポイントについて詳しく説明してください
__iter__()
イテレータを返します。ジェネレータはイテレータなので、この目的で使用できます。3再:私はここでしか推測することができますが、私はあればと思い__iter__()
不足している、または戻りませんself
反復子があるため、それは、イテレータではありません__iter__()
返すことがありますself
。
それが誰かに役立つかどうかはわかりませんが、頭の中の概念を視覚化して理解を深めたいと思っています。だから私は小さな息子がいるので、レンガと白い紙で反復可能/反復のコンセプトを視覚化します。
暗い部屋にいて、床には息子用のレンガがあるとします。異なるサイズ、色のレンガは今は問題ではありません。このようなレンガが5つあるとします。これらの5つのレンガはオブジェクトとして説明できます。たとえば、レンガキットとしましょう。このレンガキットを使用すると、多くのことができます。1つ取り、2つ目、3つ目を取り、レンガの場所を変更し、最初のレンガを2つ目のブロックの上に置くことができます。私たちはそれらでいろいろなことをすることができます。したがって、このレンガキットは、各レンガを通過して何かを行うことができるため、反復可能なオブジェクトまたはシーケンスです。私たちができるのは私の小さな息子のようにだけです。一度に1つのレンガで遊ぶことができます。だから私はこのレンガキットが自分自身であることを想像します反復可能。
今、私たちは暗い部屋にいることを思い出してください。またはほとんど暗い。問題は、それらのレンガ、それらの色、形などがはっきりと見えないことです。したがって、それらを使って何かをしたい場合、つまり、それらを繰り返し処理する場合でも、何でどのようにしているかはわかりません。暗すぎます。
私たちにできることは、最初のレンガの近くに–レンガキットの要素として–最初のレンガ要素がどこにあるかを確認するために、白い蛍光紙を置くことができます。そして、キットからレンガを取り出すたびに、暗い部屋でそれを確認できるように、白い紙を次のレンガに交換します。この白い紙はイテレータにすぎません。それもオブジェクトです。しかし、イテラブルオブジェクトの要素を操作および操作できるオブジェクト、つまりレンガキットです。
ところで、IDLEで次のことを試してTypeErrorを受け取ったときの初期の間違いを説明します。
>>> X = [1,2,3,4,5]
>>> next(X)
Traceback (most recent call last):
File "<pyshell#19>", line 1, in <module>
next(X)
TypeError: 'list' object is not an iterator
リストXはレンガのキットでしたが、白い紙ではありませんでした。最初にイテレータを見つける必要がありました:
>>> X = [1,2,3,4,5]
>>> bricks_kit = [1,2,3,4,5]
>>> white_piece_of_paper = iter(bricks_kit)
>>> next(white_piece_of_paper)
1
>>> next(white_piece_of_paper)
2
>>>
それが役立つかどうかはわかりませんが、私には役立ちました。誰かがコンセプトの視覚化を確認/修正できたら、ありがたいです。もっと学ぶのに役立ちます。
反復可能な: -反復可能である何かが反復可能です。リスト、文字列などのようなシーケンス。__getitem__
メソッドまたはメソッドのいずれかを持っています__iter__
。iter()
そのオブジェクトで関数を使用すると、イテレータが取得されます。
Iterator:- iter()
関数からiteratorオブジェクトを取得したとき。__next__()
メソッド(python3の場合)または単にnext()
(python2の場合)を呼び出して、要素を1つずつ取得します。このクラスまたはこのクラスのインスタンスは、イテレーターと呼ばれます。
ドキュメントから:-
イテレータの使用はPythonに浸透し、統一します。背後で、forステートメントがiter()
コンテナオブジェクトを呼び出し ます。この関数は__next__()
、コンテナ内の要素に1つずつアクセスするメソッドを定義する反復子オブジェクトを返します 。要素がなくなると __next__()
、StopIteration例外が発生し、forループに終了を通知します。 組み込み関数__next__()
を使用してメソッドを 呼び出すことができます next()
。この例は、すべてがどのように機能するかを示しています。
>>> s = 'abc'
>>> it = iter(s)
>>> it
<iterator object at 0x00A1DB50>
>>> next(it)
'a'
>>> next(it)
'b'
>>> next(it)
'c'
>>> next(it)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
next(it)
StopIteration
クラスの例:-
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, data):
self.data = data
self.index = len(data)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
>>> rev = Reverse('spam')
>>> iter(rev)
<__main__.Reverse object at 0x00A1DB50>
>>> for char in rev:
... print(char)
...
m
a
p
s
私はあなたがドキュメントよりもはるかに簡単にそれを得ることができるとは思いませんが、私は試してみます:
Iteratorは、iterableの次の(または最初の)アイテムを提供(または保持)するヘルパー疑似メソッド(または疑似属性)と考えることができます。(実際には、メソッドを定義するのは単なるオブジェクトですnext()
)
b:一連のコンピューター命令を指定された回数または条件が満たされるまで繰り返す—再帰を比較する
iterable = [1, 2]
iterator = iter(iterable)
print(iterator.__next__())
print(iterator.__next__())
そう、
iterable
あるオブジェクトことができ超えるループが。たとえば、リスト、文字列、タプルなど。
オブジェクトでiter
関数を使用するiterable
と、イテレータオブジェクトが返されます。
このイテレータオブジェクトには__next__
、(Python 3またはnext
Python 2 のみで)という名前のメソッドがあり、これを使用して反復可能オブジェクトの各要素にアクセスできます。
したがって、上記のコードの出力は次のようになります。
1
2
イテラブルとイテレータを扱う前に、イテラブルとイテレータを決定する主な要素はシーケンスです
シーケンス:シーケンスはデータのコレクションです
Iterable:Iterableは、__iter__
メソッドをサポートするシーケンス型オブジェクトです。
Iterメソッド:Iterメソッドはシーケンスを入力として取り、イテレーターとして知られるオブジェクトを作成します
イテレーター:イテレーターは、次のメソッドを呼び出し、シーケンスを横切るオブジェクトです。次のメソッドを呼び出すと、現在横断しているオブジェクトが返されます。
例:
x=[1,2,3,4]
xは、データのコレクションで構成されるシーケンスです
y=iter(x)
呼び出すiter(x)
と、xオブジェクトにiterメソッドがある場合にのみイテレータが返されます。それ以外の場合は例外が発生します。イテレータを返す場合、yは次のように割り当てられます。
y=[1,2,3,4]
yはイテレータなので、next()
メソッドをサポートします
nextメソッドを呼び出すと、リストの個々の要素が1つずつ返されます。
シーケンスの最後の要素を返した後、次のメソッドを再度呼び出すと、StopIterationエラーが発生します。
例:
>>> y.next()
1
>>> y.next()
2
>>> y.next()
3
>>> y.next()
4
>>> y.next()
StopIteration
Pythonでは、すべてがオブジェクトです。オブジェクトが反復可能であるとは、オブジェクトをコレクションとしてステップ実行(つまり反復)できることを意味します。
たとえば、配列は反復可能です。forループでそれらをステップ実行し、インデックス0からインデックスnに移動できます。nは、配列オブジェクトの長さから1を引いたものです。
辞書(キー/値のペア、連想配列とも呼ばれます)も反復可能です。あなたは彼らの鍵を踏むことができます。
明らかに、コレクションではないオブジェクトは反復可能ではありません。たとえば、boolオブジェクトにはTrueまたはFalseの1つの値しかありません。反復可能ではありません(反復可能オブジェクトであるとは意味がありません)。
iter()
標準のコレクション型を呼び出すことによって作成された反復子オブジェクトは反復可能ですが、それ自体はコレクションではありません。
collections.abc.AsyncIterator
テストに注意してください。これは3.6の新しい追加です。__aiter__
__anext__