コード内に for ループを記述しないように挑戦する必要があるのはなぜでしょうか?これにより、より高度で慣用的な構文やライブラリの使用方法を学習する必要があるからです。この記事では、例として Python を使用して、誰もが他の人のコードで見たことはあっても、自分ではめったに使用しない多くの構文について説明します。
Python の素晴らしい言語機能を探索し始めてから、しばらく時間が経ちました。最初は、他のプログラミング言語でのプログラミング経験よりも多くの Python 言語機能を練習できるようにすることを目標として、自分自身に課題を与えました。これにより、物事はますます面白くなります。コードはますます簡潔になり、コードはより構造化され、標準化されたように見えます。これらの利点については以下で説明します。
for ループは通常、次の使用シナリオで使用されます:
幸いなことに、Python にはこれを行うためのツールがすでにたくさんあります。必要なのは、頭を切り替えて、別の視点から考えるだけです。
for ループの記述を避けることで得られる利点:
次のコード構造を見てみましょう:
# 1 with ...: for ...: if ...: try: except: else:
この例では、読みにくい複数レベルのネストされたコードを扱っています。この例では、複数レベルのネストされたコードを使用します。このコードで私が発見したのは、管理ロジック (with、try-excel) とビジネス ロジック (for、if) を混合するためにインデントが無差別に使用されていることです。管理ロジックにのみインデントを使用するという規則に従う場合は、コアのビジネス ロジックをすぐに取り出す必要があります。
「入れ子構造よりもフラット構造の方が優れています」 - The Zen of Python
既存のツールを使用して for ループを置き換えることができます
簡単な例を見てみましょう。ある配列を別の配列に変換したい場合:
result = [] for item in item_list: new_item = do_something_with(item) result.append(item)
MapReduce が好きなら、map や Python のリスト内包表記も使用できます:
result = [do_something_with(item) for item in item_list]
同様に、単に反復処理したい場合配列内の要素と同じコードのジェネレータ式を使用することもできます。 result = (do_something_with(item) for item_list)
ある配列を別の配列にマップする場合は、map 関数を呼び出すだけで、更新された高度でより実用的なプログラミングのアプローチがこの問題を解決します。
doubled_list = map(lambda x: x * 2, old_list)
シーケンスを 1 つに削減したい場合は、reduce を使用します
さらに、多くの Python 組み込み関数はイテラブルを使用します:
>>> a = list(range(10)) >>> a [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] >>> all(a) False >>> any(a) True >>> max(a) 9 >>> min(a) 0 >>> list(filter(bool, a)) [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> set(a) {0, 1, 2, 3, 4, 5, 6, 7, 8, 9} >>> dict(zip(a,a)) {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9} >>> sorted(a, reverse=True) [9, 8, 7, 6, 5, 4, 3, 2, 1, 0] >>> str(a) '[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]' >>> sum(a) 45
上記の 2 つの方法は、より単純なロジックを処理するのに適しています。より複雑なロジックはどうでしょうか?プログラマーとして、私たちは複雑なビジネスを抽象化するために関数を作成します。同じ考え方がここでも当てはまります。次のように書くと:
results = [] for item in item_list: # setups # condition # processing # calculation results.append(result)
明らかに、コード ブロックに多くの責任を追加しすぎています。代わりに、次のようにすることをお勧めします:
def process_item(item): # setups # condition # processing # calculation return result results = [process_item(item) for item in item_list]
入れ子関数に変更するとどうなるか:
results = [] for i in range(10): for j in range(i): results.append((i, j))
これを実現するにはリスト内包表記に変更:
results = [(i, j) for i in range(10) for j in range(i)]
If のコードブロックは内部状態を記録する必要があります:
# finding the max prior to the current item a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] results = [] current_max = 0 for i in a: current_max = max(i, current_max) results.append(current_max) # results = [3, 4, 6, 6, 6, 9, 9, 9, 9, 9]
これを実現するためにジェネレーターを使用します:
def max_generator(numbers): current_max = 0 for i in numbers: current_max = max(i, current_max) yield current_max a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] results = list(max_generator(a))
読者は「ちょっと待ってください! ジェネレーターで for ループを使用したのは不正行為です!」と尋ねるかもしれません。心配しないで、以下のコードを見てください。
自分で書かないでください。itertools が実装に役立ちます。
このモジュールは非常に単純です。このモジュールは、あなたのコードを置き換えることができると思います。ほとんどのシナリオでの元の for ループたとえば、最後の例は次のように書き換えることができます:
from itertools import accumulate a = [3, 4, 6, 2, 1, 9, 0, 7, 5, 8] resutls = list(accumulate(a, max))
また、組み合わせシーケンスを反復処理する場合は、product()、permutations() を使用する必要があります。 、組み合わせ()。
以上が3 つのオプション | for ループを放棄して、Python コードをより Python らしくします。の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。