ホームページ  >  記事  >  バックエンド開発  >  課題: Python でループを実装する代替案

課題: Python でループを実装する代替案

WBOY
WBOY転載
2023-05-07 09:28:071140ブラウズ

挑战不再写Python for 循环

Python の素晴らしい言語機能を探索し始めてから、しばらく時間が経ちました。最初は、他のプログラミング言語でのプログラミング経験よりも多くの Python 言語機能を練習できるようにすることを目標として、自分自身に課題を与えました。これにより、物事はますます面白くなります。コードはますます簡潔になり、コードはより構造化され、標準化されたように見えます。これらの利点については以下で説明します。

for ループは通常、次の使用シナリオで使用されます:

  • シーケンス内の一部の情報を抽出するため。
  • あるシーケンスから別のシーケンスを生成します。
  • 書くことが習慣になりました。

幸いなことに、Python にはこれを行うためのツールがすでにたくさんあります。必要なのは、頭を切り替えて、別の視点から考えるだけです。

for ループの記述を避けることで得られる利点:

  • コード量の削減
  • コードの可読性の向上
  • インデントの減少 (それでもPython の意味)

次のコード構造を見てみましょう:

# 1
with ...:
 for ...:
 if ...:
 try:
 except:
 else:

この例では、読みにくい複数レベルのネストされたコードを扱っています。この例では、複数レベルのネストされたコードを使用します。このコードで私が発見したのは、管理ロジック (with、try-excel) とビジネス ロジック (for、if) を混合するためにインデントが無差別に使用されていることです。管理ロジックにのみインデントを使用するという規則に従う場合は、コアのビジネス ロジックをすぐに取り出す必要があります。

  • 「入れ子構造よりもフラット構造の方が優れています」 - The Zen of Python

for ループの置き換えに使用できる既存のツール

1.リスト内包表記 / ジェネレーター式

簡単な例を見てみましょう。ある配列を別の配列に変換したい場合:

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 in item_list)

2. 関数

配列を別の配列にマップする場合は、map 関数を呼び出すだけで、より高度で実用的なプログラミング方法でこの問題を解決できます。

doubled_list = map(lambda x: x * 2, old_list)

シーケンスを 1 つに減らす場合は、reduce

from functools import reduce
summation = reduce(lambda x, y: x + y, numbers)

を使用します。また、多くの 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

3。関数またはジェネレーター

上記の 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()、combination() を使用する必要があります。

結論

  • ほとんどの場合、for ループを記述する必要はありません。 ##コードを読みやすくするため、for ループの記述は避けるべきです。

以上が課題: Python でループを実装する代替案の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事は51cto.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。