次の Python スニペットを検討してください。
af=open("a",'r')
bf=open("b", 'w')
for i, line in enumerate(af):
if i < K:
bf.write(line)
ここで、K
isのケースを処理したいとNone
します。そのため、書き込みはファイルの最後まで続きます。私は現在やっています
if K is None:
for i, line in enumerate(af):
bf.write(line)
else:
for i, line in enumerate(af):
bf.write(line)
if i==K:
break
コードを複製しているため、これは明らかにこれを処理する最善の方法ではありません。これを処理できる統合された方法はありますか? が存在しないif/break
場合にのみコードが存在するようにするのが自然なことですが、これには Lisp マクロのようにオンザフライで構文を書くことが含まれますが、これは Python では実際にはできません。明確にするために、私は特定のケース (部分的に単純にするために選択した) については心配していません。K
None
更新: 人々が投稿した回答を読み、さらに実験を行った後、いくつかのコメントがあります。
上記のように、私は一般化できる一般的な手法を探していました.@Paulの答え、つまりtakewhile
fromを使用するのiterrools
が最適だと思います。おまけとして、上記の単純な方法よりもはるかに高速です。理由はわかりません。itertools
何度か見たことはありますが、あまり詳しくありません。私の観点からすると、これはFor The Win !の関数型プログラミングのケースです。(面白いことに、 の作成者は、 のitertools
ドロップについてフィードバックを求めたことがあります。 http://mail.python.org/pipermail/python-list/2007-December/522529.htmltakewhile
で始まるスレッドを参照してください。) 上記の状況を単純化したところ、実際の状況はもう少し厄介です。ループ内の 2 つの異なるファイルに書き込んでいます。したがって、コードは次のようになります。
for i, line in enumerate(af):
if i < K:
bf.write(line)
cf.write(line.split(',')[0].strip('"')+'\n')
私の投稿された例を考えると、@Jeff は合理的に、 is の場合はファイルをコピーすることを提案しましK
たNone
。実際にはとにかくループしているので、そうするのはそれほど明確な選択ではありません。ただし、takewhile
この場合は簡単に一般化できます。ここでは言及していない別のユースケースもtakewhile
あり、そこでも使用できてよかったです。2番目の例は次のようになります(逐語的に)
i=0
for line in takewhile(illuminacond, af):
line_split=line.split(',')
pid=line_split[1][0:3]
out = line_split[1] + ',' + line_split[2] + ',' + line_split[3][1] + line_split[3][3] + ',' \
+ line_split[15] + ',' + line_split[9] + ',' + line_split[10]
if pid!='cnv' and pid!='hCV' and pid!='cnv':
i = i+1
of.write(out.strip('"')+'\n')
tf.write(line)
ここで条件を使用できました
if K is None:
illuminacond = lambda x: x.split(',')[0] != '[Controls]'
else:
illuminacond = lambda x: x.split(',')[0] != '[Controls]' and i < K
@Paulの元の例ごと。i
ただし、コードは機能しますが、外側のスコープから取得しているという事実に完全に満足しているわけではありません。これを行うより良い方法はありますか?または、別の質問にする必要があるかもしれません。とにかく、私の質問に答えてくれたみんなに感謝します。いくつかの素晴らしい提案をしてくれた@Jeffへの名誉ある言及。