ホームページ >バックエンド開発 >Python チュートリアル >Python のいくつかの高度な機能
私は Python を使い始めて約半年になります。最初の混乱からいくつかの小さなクローラーを作成し、最終的に使い始めるまで、Python を使い始めました。割り当て、基本的に C++ を放棄します。でも、まだ少しせっかちなので、短いコードは書けますが、Python の機能を知らない、または忘れていることが多いので、Liao Da のチュートリアルに戻って復習し、思ったことを記録します。の方が重要です。
この記事は主にLiao Daのチュートリアルの高度な機能セクションの内容を記録し、私の理解の一部を書き留めます。私の意見では、これらの機能は非常に Python 的で、コードで使用すると非常に大きくなります。
スライスと反復については説明しません。まず名前から見てみましょう。これらは、次のようなリストを生成するいくつかの方法であると大まかに推測できます: [1*1, 2*2, ... ,10*10]
を生成するには? Python メソッド、つまりリスト生成式を使用する場合は、ループを使用してリストの末尾に要素を継続的に追加できます。
>>> [x * x for x in range(1, 11)] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
また、次のように if 判定を続けることもできます。
>>> [x * x for x in range(1, 11) if x%2==0] [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
このように、ループを使用して記述する必要がある4、5行のコードを1行で解決でき、直感的で明確です。
2 つの for ループを使用して完全な順列を生成することもできます:
>>> [m + n for m in 'ABC' for n in 'XYZ'] ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
この方法で if 判定を追加するにはどうすればよいですか?各 for ステートメントの後に追加することも、最後に追加することもできます:
>>> [m + n for m in 'ABC' if m < 'C' for n in 'XYZ' if n < 'Z'] ['AX', 'AY', 'BX', 'BY'] >>> [m + n for m in 'ABC' for n in 'XYZ' if n < 'Z' and m < 'C'] ['AX', 'AY', 'BX', 'BY']
for ステートメントで複数の変数を同時に反復することもできます。たとえば、dict の items() はキーと値を同時に反復できます。 :
>>> d = {'x': 'A', 'y': 'B', 'z': 'C' } >>> [k + '=' + v for k, v in d.items()] ['y=B', 'x=A', 'z=C']
それはそれです〜
しかし、私はこれまでずっと C++ を書いていましたが、この構文に慣れてしまうと、徐々に慣れるしかありません。無意識のうちに書くことができます。
なぜジェネレーターを使用するのですか? Liao Da のチュートリアルで詳細に説明されていますが、ここでは簡単に要約します:
リストの内容はメモリに配置され、メモリ制限の影響を受けるため、リストの容量は限られています。
ごく少数の要素にのみアクセスすると、スペースが膨大に無駄になります。
理論的には、ジェネレーターは反復中に次の値を計算でき、プロセスは無限に継続でき、多くのメモリを占有しません。
ここでは簡単な紹介をします。詳細についてはGoogleで調べてください~
ジェネレーターの作成方法?最初のメソッドは、前述のリスト生成と似ています。[] を () に変更するだけです。
>>> L = [x * x for x in range(10)] >>> L [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] >>> g = (x * x for x in range(10)) >>> g <generator object <genexpr> at 0x1022ef630>
メソッドがほぼ同じであることがわかります。[] で得られるのは、すべての値を取得したリストです。 . , () は、for ループを使用して反復できるジェネレーターを取得しますが、添字を使用してジェネレーターにアクセスすることはできず、再度反復すると、StopIteration 例外が発生します。ジェネレーターを作成した後、基本的に next() は呼び出されず、代わりに for ループを通じて反復されるため、StopIteration エラーを気にする必要はありません。
計算アルゴリズムがより複雑で、リスト生成と同様の for ループを使用して実装できない場合は、関数を使用して実装することもできます。たとえば、有名なフィボナッチ数列:
>>> for i in g: ... print(i) ... 0 1 4 9 16 25 36 49 64 81 >>> for i in g: ... print(i) ... >>> next(g) Traceback (most recent call last): File "<stdin>", line 1, in <module> StopIteration
キーワード yield については、私は次のように考えています。 Pythonを初めて勉強したときはジェネレーターを見るまでは理解できずに苦労しましたが、これは一つか二つしか言えません。文章ですが、間違ったことを言うのが怖いです。 Liao Da のチュートリアルには次のように書かれています:
関数は順番に実行され、return ステートメントまたは関数ステートメントの最後の行に遭遇すると戻ります。ジェネレーターとなる関数は next() が呼び出されるたびに実行され、yield ステートメントに遭遇するとリターンし、再度実行されると最後に返された yield ステートメントから実行を継続します。少しわかりにくいかもしれませんが、一度理解すれば説明は簡単です。
もちろん、ジェネレーター関数に return を追加することもできます。return がない場合、デフォルトでは関数が完了するまで実行されます。実行中にリターンした場合は、直接 StopIteration がスローされます。反復。
たとえば、上記の例では、戻り値が例外値として扱われたため、反復中に「done」の文字列が表示されないことがわかりました。これを表示したい場合は、次のようにすることができます:
def fib(max): n, a, b = 0, 0, 1 while n < max: yield b a, b = b, a + b n = n + 1 return 'done'
Iterator )
>>> g = fib(6) >>> while True: ... try: ... x = next(g) ... print('g:', x) ... except StopIteration as e: ... print('Generator return value:', e.value) ... break ... g: 1 g: 1 g: 2 g: 3 g: 5 g: 8 Generator return value: done
上記の 2 つの例を通して、次のように理解できます: ジェネレーターとリスト、タプル、str などはすべて Iterable ですオブジェクトであり、ジェネレーターも Iterator オブジェクトですが、リストなどはそうではありません。では、Iterable オブジェクトから Iterator オブジェクトに直接変換できるのでしょうか?
iter() 関数を使用できます:
>>> isinstance(iter([]), Iterator) True >>> isinstance(iter('abc'), Iterator) True
其实,Iterator 对象表示的是一个数据流,我们可以把这个数据流看做是一个有序序列,但却不能提前知道序列的长度,只能不断通过next()函数实现按需计算下一个数据,所以 Iterator 的计算是惰性的,只有在需要返回下一个数据时它才会计算。Iterator甚至可以表示一个无限大的数据流,但 list,tuple 什么的是不可能这样的。
更多关于 python 的一些高级特性相关文章请关注PHP中文网!