【Python備忘録】Perlのアレを、Pythonでどう書けばよいか #03
投稿日: / 更新日:
この記事は2年以上前に書かれたものです。情報が古い可能性があります。
お題: 標準入力からCSVを受け取り、特定の列の数値の合計を出力する。なお、値に数値以外が含まれている場合は、その値を無視する。
1. Perl 5
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#!/usr/bin/env perl use strict; use warnings; my $column = 1; # left to right, starts with 0 my $sum = 0; while (my $line = <>) { chomp $line; my $value = (split q{,}, $line)[$column]; $sum += $value if $value =~ m{\A \d+ \z}xms; # $sum += $value unless $value =~ m{\D}xms; # more literal } print "sum: $sum\n"; |
2. Python 2.7
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
#!/usr/bin/env python2.7 import sys import re column = 1 # left to right, starts with 0 sum = 0 for line in sys.stdin: value = (line.rstrip('\n').split(','))[column] if re.match('\A\d+\Z', value): sum += int(value) print "sum: " + str(sum) # ポイント1: # 標準入力を読み込むためにsysモジュール、 # 正規表現のパターンマッチングを使用するためにreモジュールを、 # それぞれインポートしておく必要がある。 # ポイント2: # 標準入力ストリーム(sys.stdin)はfileオブジェクトであり、 # "for ~ in ~"構文で評価すると、入力から1行ずつ取得して、 # 変数に自動的に代入してくれる。 # ポイント3: # Perl 5のchompに相当するrstrip()メソッドは、 # 末尾の改行文字や空白文字を取り除いた後の文字列を返す。 # chompと異なり、返される文字列はオブジェクトであるため、 # そのままメソッドチェーンでsplit()することが可能。 # ポイント4: # Perl 5と異なり、「文字列の末尾」を表すアンカーは\Zとなる。 # 複数行モードにするには、"re.MULTILINE"の指定が必要。 |
3. (おまけ) Perl 6 (Rakudo 2016.07.1)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
#!/usr/bin/env perl6 my $column = 1; # left to right, starts with 0 my $sum = 0; for $*IN.lines() -> $line { my $value = ($line.chomp.split(','))[$column]; $sum += $value if $value ~~ m{^ \d+ $}; # $sum += $value unless $value ~~ m{\D}; # more literal } say "sum: $sum"; # ポイント1: # strictとwarningsプラグマは、デフォルトで有効となっている。 # ただしwarningsについては、プラグマとして実装されていない模様。 # ポイント2: # 標準入力ファイル記述子($*IN)のlines()メソッドにより、 # Pythonと同様に、for文で1行ずつ取得して変数へ代入が可能。 # なお、"$*IN."を省略してlines()だけ書いても同じ意味になる。 # ポイント3: # for構文の"->"はfat commaではなく、構文の一部である。 # ","に置き換えると文法エラーとなる。 # ポイント4: # chomp、splitいずれも文字列(Str)のメソッドとしても呼び出し可能。 # これを利用し、Pythonと同様にメソッドチェーンにすることができる。 # ポイント5: # 文字列の連結演算子が"."から"~"に変更されたことに伴い、 # 正規表現のマッチング演算子が"=~"から"~~"に変更された。 # ポイント6: # 正規表現のパターンにおいて、メタキャラクタの^と$が、Perl 5の # \Aと\zと同じ意味を持つようになった。従来の^と$を表したい場合は、 # それぞれ^^、$$を使う。 # ポイント7: # 正規表現の修飾子(Modifiers)は、副詞(Adverbs)に取って代わられた。 # また、Perl 5のベストプラクティスの"xms"は、いずれもデフォルトで # 有効になっている。 |