Java/Python 導入ガイド《2》for 文を使って
Java プログラマーのための Python 導入ガイド〈初級/入門編〉《Jython2.5.0》
《2》for 文を使って
》作業中です《 2006年6月27日 (火)
いきなり最終回
最初に結論を示します。次のような、Java 版の関数と同等以上のものを目指して、
static void filter(Collection c) { for (Iterator it = c.iterator(); it.hasNext(); ) if (!cond(it.next())) it.remove(); }
Python 版の関数では、次のようになりました。
def xfilter(c, cond): # for e in filter(lambda e: cond(e), c): for e in [e for e in c if cond(e)]: if isinstance(c, dict): del c[e] else: c.remove(e)
これらの重要な違いが分かりますか。そこに至るまでの物語が、ここから始まります。
■ for 文を使って
Java の公式サイトには、次の《事例》が紹介してあります。
// for-each Construct for (Object o : collection) System.out.println(o);
C言語の伝統を継承する for 文には、情報隠蔽の原則に反する致命的な欠点があります(詳細は、ブログの関連記事「for と別れる50の方法」を参照してください)。拡張 for 文を使うと、情報隠蔽の原則に沿って、仕様変更にも柔軟に対処できるので、些末な単純作業から開放され、より本質的な作業に専念できるようになります。
■ 文字列:String
>>> for e in "ABC": print e, A B C
Java で文字列を扱うクラス String に相当するのが、Python の組み込み型 str です。for に続く変数 e は、文字列の各要素を「先頭から順に」参照します。先頭の文字 A に続けて、2番目の文字 B を、そして最後に、末尾の文字 C を出力します。
JPL: p.240 には、拡張 for 文について「The for statement is read "for each val in values" and each time through the loop ...」とあります。Python における for 文は、冗長な括弧が不要になるので、次のように「読んで字のごとく」
>>> values = "ABC" >>> for each in values: print each
「英文の一節を読んでいる」ような感覚で、自然にコードを記述できます。
■ リスト:List
>>> [e for e in "ABC"] ['A', 'B', 'C'] >>> for e in ['A', 'B', 'C']: print e, A B C
Java でリストを扱う List に相当するのが、Python の組み込み型 list です。for に続く変数 e は、リストの各要素を「先頭から順に」参照します。すると、先の事例と同様に、文字を順に出力します。
list のリテラル表現を使って、括弧 [] 内にカンマ「,」で区切った要素を列挙したものを評価すると、同じ要素を持つインスタンスが得られます。
■ 集合:Set
>>> set([e for e in "ABC"]) set(['A', 'C', 'B']) >>> for e in set(['A', 'B', 'C']): print e, A C B
Java で集合を扱う Set に相当するのが、Python の組み込み型 set です。for に続く変数 e は、集合の各要素を「任意の順序で」参照します。すると、先の事例と同様に、文字を順に出力します。ただし、その結果は順不同となります。
組み込み関数 set の引数に、リテラル表現の list を指定すると、その要素をもとに、set のインスタンス(要素が重複しないもの)を生成します。
■ 写像:Map
>>> dict([(e,ord(e)) for e in "ABC"]) {'A': 65, 'C': 67, 'B': 66} >>> for e in {'A': 65, 'C': 67, 'B': 66}: print e, A C B
Java で写像を扱う Map に相当するのが、Python の組み込み型 dict です。for に続く変数 e は、辞書の各キー要素を「任意の順序で」参照します。すると、先の事例と同様に、文字を順に出力します。ただし、その結果は順不同となります。
組み込み関数 dict の引数に、タプルを要素とする list のインスタンスを指定すると、その要素対(キー/値)をもとに、dict のインスタンスを生成します。
dict のリテラル表現を使って、括弧 {} 内にコロン「:」で区切った要素対(キー/値)を列挙したものを評価すると、同じ要素対を持つインスタンスが得られます。