リスト内包表記
- d.y.d: 内包表記 (http://www.kmonos.net/wlog/82.html#_1753080218)
リスト内包表記で一時変数を使用したいがために無駄なforループを1つ増やしているということだが、問題点は以下の3つ。
- 式しか書けないので代入文が書けない
- sys.stdinから読み取ってsplitしたやつで回したいのに、2段階に分けないといけない
- 式が1つしか書けないので、初期化したり、途中で代入したりする場所がない
1つ目は、書き方は汚いが代入文を式に変換する方法がある。2つ目は、__iter__をオーバーライドする方法がある。もしくは一時変数に保存しておけば良い。3つ目は、ifの後や結果の式中に無理やり書ける。
以下2通りの方法を考えたが、いずれも汚い。結局、きれいに書くにはPythonのポリシー通り内包表記でなくfor文で普通に書くしか思いつかない...。我ながら勉強不足。以下はコード断片。
NFOアプローチ版。
import sys def foo():pass [foo.kv[1] for line in sys.stdin if setattr(foo, 'kv', line.split()) or foo.kv[0] in tags]
__iter__をオーバーライド版。
import sys from StringIO import * class file2(StringIO): def __iter__(self): while True: line = self.next() yield line.split() [v for k, v in file2(sys.stdin.read()) if k in tags]
このケースでは不可能だが、似た問題の別のアプローチは私の過去の日記で作成したflatten_forで複数ループを1重ループに落とし込む方法とか。permutationという関数名でitertoolsもしくはビルトインに入れて欲しいなあ。