「おそらく知らなかった4つのPython Itertoolsフィルター関数」

4 Python Itertools Filter Functions You Probably Didn't Know

 

Pythonでは、イテレータを使用することで、よりPythonicなコードを書くことができ、長いシーケンスをより効率的に処理することができます。組み込みのitertoolsモジュールは、いくつかの便利な関数を提供して、イテレータを作成します。

これらは、イテレータを単にループしてシーケンス内の要素を取得し、それらを処理する場合に特に役立ちます。すべての要素をメモリに格納することなく、これらの関数を使用する方法を学びましょう。今日は以下の4つのitertoolsフィルタ関数の使用方法を学びます:

  • filterfalse
  • takewhile
  • dropwhile
  • islice

では、始めましょう!

 

始める前に: コード例に関する注意事項

 

このチュートリアルでは:

  • 4つの関数はすべてイテレータを返します。わかりやすさのため、単純なシーケンスで作業し、list()を使用してイテレータが返すすべての要素を含むリストを取得します。ただし、長いシーケンスで作業する場合は、必要な場合以外はこれを行わないでください。なぜなら、そうするとイテレータのメモリの節約効果が失われるからです。
  • 単純な述語関数の場合、ラムダを使用することもできます。ただし、可読性のために、通常の関数を定義して述語として使用します。

 

1. filterfalse

 

Pythonで長い間プログラミングをしている場合、おそらく組み込みのfilter関数を次のような構文で使用したことがあるでしょう:

filter(pred,seq)
# pred: 述語関数
# seq: 有効なPythonのイテラブル

 

filter関数は、述語がTrueを返すシーケンスの要素を返すイテレータを返します。

例を見てみましょう:

nums = list(range(1,11)) #[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

def is_even(n):
    return n % 2 == 0

 

ここで、numsリストとis_even関数は、シーケンスと述語です。

numsのすべての偶数のリストを取得するには、次のようにfilterを使用します:

nums_even = filter(is_even, nums)
print(list(nums_even))

 

出力 >>> [2, 4, 6, 8, 10]

 

次に、filterfalseについて学びましょう。 filterfalse関数(および他のすべての関数)をitertoolsモジュールからインポートします。

名前からわかるように、filterfalsefilter関数の逆の動作をします。述語がFalseを返す要素を返すイテレータを返します。 filterfalse関数の構文は次のとおりです:

from itertools import filterfalse
filterfalse(pred,seq)

 

is_even関数はnumsのすべての奇数に対してFalseを返します。したがって、filterfalseを使用して取得されるnums_oddリストは、numsのすべての奇数のリストです:

from itertools import filterfalse

nums_odd = filterfalse(is_even, nums)
print(list(nums_odd)) 

 

出力 >>> [1, 3, 5, 7, 9]

 

2. takewhile

 

takewhile関数を使用するための構文は次のとおりです:

from itertools import takewhile
takewhile(pred,seq)

 

takewhile関数は、述語関数がTrueを返す限り要素を返すイテレータを生成します。述語がFalseを返した場合、要素の返却を停止します。

n要素のシーケンスに対して、述語関数がFalseを返す最初の要素がseq[k]である場合、イテレータはseq[0], seq[1],…, seq[k-1]を返します。

以下のnumsリストと述語関数is_less_than_5を考えてみましょう。以下のようにtakewhile関数を使用します:

from itertools import takewhile

def is_less_than_5(n):
    return n < 5

nums = [1, 3, 5, 2, 4, 6]
filtered_nums_1 = takewhile(is_less_than_5, nums)
print(list(filtered_nums_1))  

 

ここでは、述語is_less_than_5は数値5に対して最初のFalseを返します:

出力 >>> [1, 3]

 

3. dropwhile

 

機能的には、dropwhile関数はtakewhile関数の逆を行います。

以下のようにdropwhile関数を使用することができます:

from itertools import dropwhile
dropwhile(pred,seq) 

 

dropwhile関数は、述語がTrueである限り要素を除外し続けるイテレータを生成します。述語が最初のFalseを返すまでは何も返しません。そして、述語がFalseを返した後は、シーケンス内のその後の要素をすべて返します。

n要素のシーケンスに対して、述語関数がFalseを返す最初の要素がseq[k]である場合、イテレータはseq[k], seq[k+1],…, seq[n-1]を返します。

同じシーケンスと述語を使用してみましょう:

from itertools import dropwhile

def is_less_than_5(n):
    return n < 5

nums = [1, 3, 5, 2, 4, 6]
filtered_nums_2 = dropwhile(is_less_than_5, nums)
print(list(filtered_nums_2)) 

 

述語関数is_less_than_5は最初のFalseとして要素5を返すため、シーケンスの要素5から始まるすべての要素が返されます:

出力 >>> [5, 2, 4, 6]

 

4. islice

 

すでにリスト、タプル、文字列などのPythonの反復可能なオブジェクトのスライシングについてはおなじみでしょう。スライシングの構文はiterable[start:stop:step]です。

ただし、このスライシングの方法には以下のような欠点があります:

  • 大きなシーケンスで作業する場合、各スライスまたは部分シーケンスはメモリを占有するコピーです。これは非効率的です。
  • ステップには負の値も使用できるため、開始、停止、およびステップの値を使用すると可読性に影響します。

islice関数は上記の制約に対処します:

  • イテレータを返します。
  • ステップには負の値を使用することはできません。

以下のようにislice関数を使用することができます:

from itertools import islice
islice(seq,start,stop,step) 

 

以下は、islice関数を使用するいくつかの異なる方法です:

  • islice(seq, stop)を使用すると、seq[0]seq[1]、…、seq[stop - 1]のスライス上で反復するイテレータが返されます。
  • 開始値と終了値を指定する場合:islice(seq, start, stop)は、seq[start]seq[start + 1]、…、seq[start + stop - 1]のスライス上で反復するイテレータが返されます。
  • 開始値、終了値、ステップ引数を指定する場合、関数はseq[start]seq[start + step]seq[start + 2*step]、…、seq[start + k*step]のスライス上で反復するイテレータを返します。ただし、start + k*step < stop かつ start + (k+1)*step >= stopとなるようにします。

これをよりよく理解するために、例としてリストを使用しましょう:

nums = list(range(10)) #[0,1, 2, 3, 4, 5, 6, 7, 8, 9]

 

では、学んだ構文を使用してislice関数を使ってみましょう。

 

ストップ値のみを使用する

 

ストップインデックスのみを指定しましょう:

from itertools import islice

# only stop
sliced_nums = islice(nums, 5)
print(list(sliced_nums)) 

 

以下は出力です:

出力 >>> [0, 1, 2, 3, 4]

 

開始値と終了値を使用する

 

ここでは、開始値と終了値の両方を使用します:

# start and stop
sliced_nums = islice(nums, 2, 7)
print(list(sliced_nums))

 

スライスはインデックス2から7までの範囲で、7を含まないようになっています:

出力 >>> [2, 3, 4, 5, 6]

 

開始値、終了値、ステップ値を使用する

 

開始値、終了値、ステップ値を使用する場合:

# using start, stop, and step
sliced_nums = islice(nums, 2, 8, 2)
print(list(sliced_nums))  

 

インデックス2から8までの範囲で、ステップサイズが2(2つおきに返す)のスライスが得られます。

出力 >>> [2, 4, 6]

 

まとめ

 

このチュートリアルがitertoolsのフィルタ関数の基本を理解するのに役立ったことを願っています。これらの関数の動作をよりよく理解するためのいくつかの簡単な例を見ました。次に、効率的なPythonイテレータとしてのジェネレータ関数とジェネレータ式の動作について学ぶことができます。     Bala Priya Cは、インド出身の開発者兼技術ライターです。彼女は数学、プログラミング、データサイエンス、コンテンツ作成の交差点での作業が好きです。彼女の関心と専門知識の範囲には、DevOps、データサイエンス、自然言語処理が含まれます。彼女は読書、執筆、コーディング、コーヒーが好きです!現在、彼女はチュートリアル、ハウツーガイド、意見記事などを執筆することで、開発者コミュニティと彼女の知識を共有するための学習に取り組んでいます。  

We will continue to update VoAGI; if you have any questions or suggestions, please contact us!

Share:

Was this article helpful?

93 out of 132 found this helpful

Discover more

データサイエンス

「Seerの最高データオフィサーであるDr. Serafim Batzoglouによるインタビューシリーズ」

セラフィム・バツォグルはSeerのチーフデータオフィサーですSeerに加わる前は、セラフィムはInsitroのチーフデータオフィサー...

データサイエンス

アステラソフトウェアのCOO、ジェイ・ミシュラ - インタビューシリーズ

ジェイ・ミシュラは、急速に成長しているエンタープライズ向けデータソリューションの提供企業であるAstera Softwareの最高執...

AIニュース

Q&A:ブラジルの政治、アマゾンの人権、AIについてのGabriela Sá Pessoaの見解

ブラジルの社会正義のジャーナリストは、MIT国際研究センターのフェローです

人工知能

「クリス・サレンス氏、CentralReachのCEO - インタビューシリーズ」

クリス・サレンズはCentralReachの最高経営責任者であり、同社を率いて、自閉症や関連する障害を持つ人々のために優れたクラ...

機械学習

「Prolificの機械学習エンジニア兼AIコンサルタント、ノラ・ペトロヴァ – インタビューシリーズ」

『Nora Petrovaは、Prolificの機械学習エンジニア兼AIコンサルタントですProlificは2014年に設立され、既にGoogle、スタンフ...

人工知能

ディープAIの共同創業者兼CEO、ケビン・バラゴナ氏- インタビューシリーズ

ディープAIの創設者であるケビン・バラゴナは、10年以上の経験を持つプロのソフトウェアエンジニア兼製品開発者です彼の目標...