Pythonとサイクル作業のための他の言語のためのループは、同じではありません今日は、ループのためにあなたのPythonの深い理解を取り、それがどのように動作するか確認し、なぜそれがそのように動作します。
ループトラップ
私たちは、最初のサイクルの仕事の我々の理解では、Pythonのループ「罠」を見て、そして最後が起こるかある中で、これらのトラップを見てください。
トラップ1:サイクル回
さて、あなたは番号のリスト、およびこれらの番号を返すために使用される発電機の広場があるとしましょう:
>>> nums = [1, 2, 3, 4]
>>> squares = (n**2 for n in nums)
私たちは、コンストラクタに渡されたタプルオブジェクトを生成することができ、タプルを得ることができます。
>>> tuple(squares)
(1, 4, 9, 16)
私たちは、その後、オブジェクトのコンストラクタに渡された場合は、この時間は、sum
機能、および通常はこれらの数字とバーを返す必要があります:
>>> sum(squares)
0
0を返し、最初のあごを保持しています。
トラップ2:それをチェック
我々はまだ数字と発電機の上記のリストを使用します。
>>> nums = [1, 2, 3, 4]
>>> squares = (n**2 for n in nums)
私の正方形はビルダー9が含まれている場合、答えはイエスである、Ruoguoは、私は再び尋ねますか?
>>> 9 in squares
True
>>> 9 in squares
False
発見、二つ目は働いていません -
トラップ3:開梱
今の辞書があるとします。
>>> counts = {1:'a', 2:'b'}
その後、我々は複数の変数を持つ辞書を開梱しました。
>>> x,y = counts
何がこの時、xとyはなると思いますか?
>>> x
1
>>> y
2
我々は唯一の鍵を得ました。
ここでは、我々はその後、抗これまでにこれらのトラップの問題を参照するように、Pythonの下の作品のサイクルを理解するために開始します。
いくつかの概念
まずは、いくつかの基本的な概念を理解してみましょう:
そして、反復配列であることができます
イテレーションも繰り返しあなたが通過することができることを意味することができをループのために使用することができる任意のもの、反復的で横断することができます何を指します。
for item in some_iterable:
print(item)
配列は、タプル、文字列などのリストなどの反復することができ、一般的なタイプです。
反復配列は、インデックス0から開始する機能の数を有している、配列の長さを超えていないインデックス長;それらはシーケンス長を有し、そしてそれらをスライスすることができます。
Pythonのほとんどの事が可能反復のですが、あなたはそれが反復シーケンスであることを意味することはできません。セット、辞書、およびファイル・ジェネレータの反復として、それは可能ですが、彼らは配列ではありません。
>>> my_set = {1, 2, 3}
>>> my_dict = {'k1': 'v1', 'k2': 'v2'}
>>> my_file = open('some_file.txt')
>>> squares = (n**2 for n in my_set)
結論、何が反復シーケンスの一つのタイプは、Pythonは入力でき、反復他の多くの種類があることができ、反復処理をループのために利用可能で使用することができます。
イテレータ
反復オブジェクトに物事を駆動することができイテレータ。あなたはまた、手動で横断するイテレータイテレータするために使用することができ、任意の繰り返しオブジェクトからイテレータを取得することができます。
タプルの集合と文字列:ここでは3反復可能オブジェクトは、次のとおりです。
>>> nums = {1,2,3,4}
>>> coors = (4,5,6)
>>> words = "hello hoxis"
私たちは、Pythonの組み込み関数を使用することができiter
、これらは、イテレータの繰り返しにオブジェクトから取得することができます。
>>> iter(nums)
<setiterator object at 0x7fa8c194ad70>
>>> iter(coors)
<tupleiterator object at 0x7fa8c1959610>
>>> iter(words)
<iterator object at 0x7fa8c19595d0>
私たちは、イテレータを持っていたら、我々はその組み込み関数を使用することができnext()
、その次の値を取得するには:
>>> nums = {1,2,3,4}
>>> num_iter = iter(nums)
>>> next(num_iter)
1
>>> next(num_iter)
2
>>> next(num_iter)
3
>>> next(num_iter)
4
>>> next(num_iter)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
終わりに近づいて反復Ruoguoは、それが次の値ではない、それがスローされますStopIteration
例外を。言い換えれば、それは最初のサイクルが値をとり得るために続行されません。
それは少し無知強制することはありませんか?
- 反復可能オブジェクトは、反復的なものです
- 繰り返しオブジェクトは、実際にはプロキシトラバーサルイテラブル
- 何の長さをイテレータない、彼らはインデックスを作成することができません。
- あなたがするイテレータを使用することができる唯一の役に立つ事はビルトインにそれを渡すことです
next
それらを介して機能、またはサイクル - あなたは使用することができ
list()
、リストイテレータを変換する機能を
>>> nums = {1,2,3,4}
>>> num_iter = iter(nums)
>>> next(num_iter)
1
>>> list(num_iter)
[2, 3, 4]
>>> list(num_iter)
[]
Ruoguoが再びリストに変換したい、明らかに、それは空のリストを取得することです。
実際には、これはイテレータの重要な特性である:不活性な、一度だけ貫通することができる唯一のループ、一度使用することができます。我々は次の()関数を呼び出す前に、そして、それは何もしません。したがって、我々はあなたがメモリ不足になると、されない無限に長いリストを作成し、無限のイテレータを作成することができます!
必ずしもイテレータをイテラブルが、イテレータは反復である必要があります。
オブジェクト | あなたは、反復可能? | イテレータ? |
---|---|---|
反復可能オブジェクト | √ | そうとも限りません |
イテレータ | √ | √ |
ジェネレータ | √ | √ |
リスト | √ | × |
実際には、Pythonは、多くのイテレータ、発電機のイテレータがあり、Pythonの多くのビルトインタイプがイテレータです。たとえば、Pythonのenumerate
とreversed
オブジェクトがイテレータです。zip
、map
そしてfilter
また、イテレータ、ファイルオブジェクトもイテレータです。
ループ用のPython
実際には、Pythonはループのための伝統的ではない、ループの伝統的な何ですか?
私たちは、ループ用のJavaで見て:
int[] integers = {1, 2, 3, 4};
for (int j = 0; j<integers.length; j++) {
int i = integers[j];
System.out.println(i);
}
これは、C风格
ループのためには、JavaScript、C、C ++、 Javaの、PHP や他のプログラミング言語は、このサイクルのスタイルの多くを持っていますが、Pythonはありません。
私たちは呼んでループのためのPythonは、正確には、foreachのループでなければなりません。
numbers = [1, 2, 3, 5, 7]
for n in numbers:
print(n)
そしてC风格
ループのため、Pythonのループインデックス変数ノー、ノー、インデックス変数の初期化、境界チェックおよびインデックス変数の増加のためのものとは異なります。
これは、ループのためのPythonと異なっています!
インデックスを使用しますか?
あなたは、Pythonはループのために、我々はトラバーサルに手動でインデックスwhileループを使用し、ここで、下部にあるインデックスを使用している、不思議に思うことがあります。
>>> nums = [1,2,3,4]
>>> i = 0
>>> while i < len(nums):
... print(num[i])
... i += 1
...
0
1
2
3
リストについては、その横断は可能ですが、すべてのイテラブルのために、それが意味するものではありません配列のみに適用されます。
例えば、我々は例外を取得、セットを横断するために、このメソッドを使用します。
>>> set = {1,2,3}
>>> i = 0
>>> while i < len(set):
... print(set[i])
... i += 1
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
TypeError: 'set' object does not support indexing
順序が設定されていないので、それがインデックス付けを通じサポートしていません。
私たちは、Pythonオブジェクトの各反復は、手動でインデックスを横断することはできません。イテレータのシーケンスでない人のために、仕事に行くのではありません。
ないサイクルの実現のために
以上のことから、Pythonはループインデックスのために、それはイテレータを使用され、使用されていません。のは、それがどのように動作するかを見てみましょう。
以上のことから、私たちは、次の機能をイテレータとITERを学び、そして今、私たちは反復可能なオブジェクトを反復処理するループのためにやろうとすることができます。
ここでループは正常です。
def funky_for_loop(iterable, action_to_do):
for item in iterable:
action_to_do(item)
私たちは、この方法のループイテレータと同時に、一般的に次の手順については、上記のロジックを達成しようとする必要があります。
- 与えられた反復可能オブジェクトの反復子を取得します。
- 次の項目を取得するイテレータのnext()メソッドを呼び出します。
- データの現在の項目が処理されます。
- 撮影した場合は
StopIteration
、その後、ループを停止
def funky_for_loop(iterable, action_to_do):
iterator = iter(iterable)
while not done_looping:
try:
item = next(iterator)
except StopIteration:
break
else:
action_to_do(item)
Pythonのサイクルの作業は、実質的に、基礎となるコードは、ループの反復のために駆動されます。
もう一度ループトラップに戻ります
トラップ1:枯渇イテレータ
1つのトラップは、発電機がイテレータであるため、反復子は不活性であり、0が返され、一度横断した場合に、使い捨てであり、かつ、それらを合計します。
トラップ2:部分的に消費イテレータ
トラップ2では、我々は2つの9が同じビルダーに存在するかどうか、別の答えを得る尋ねました。
これは尋ねた初めて、Pythonのは、この発電機が横断されていた、ので、すなわち、9を見つけるために、次の()関数を呼び出し、trueを返しますを発見した後、二回目は9からそこにするかどうかを尋ねることです場所時間は、次の()が検索し続けます。
>>> nums = [1,2,3,4,5]
>>> squares = (n**2 for n in nums)
>>> 9 in squares
True
# 此时打印出来
>>> list(squares)
[16, 25]
トラップ3:アンパック反復であります
辞書に直接反復処理する場合は、キーを取得することです:
>>> counts = {1:'a',2:'b'}
>>> for i in counts:
... print(i)
...
1
2
辞書を開梱し、辞書トラバーサルが同じであるとき、彼らはこのようにキーまた、その結果、イテレータプロトコルに依存しています。
概要
シーケンスはイテレータではなく、すべてのイテレータは、配列です。イテレータは二回ループをすることはできません、その長さにアクセスすることはできません、インデックスを使用することはできません。
Pythonのイテレータは、最も基本的な形は、反復可能です。あなたは、コードの不活性の反復で行いたい場合は、イテレータを考慮し、発電機または関数ジェネレータ式の使用を検討してください。
最後に、Pythonのそれぞれの反復でイテレータプロトコルは、Pythonのサイクルを理解する鍵と理解し、イテレータプロトコルに依存している、ということを覚えておいてください。
オリジナルリンク:https://opensource.com/article/18/3/loop-better-deeper-look-iteration-python