2

序章

私は自分の問題に対する狡猾な解決策を思いつきましたが、それほど狡猾ではありませんが、うまくいきません:-/

デバッガーを何時間もクリックした後おそらくこれを確認できます。それが機能しない理由はitertools.dropwhile、最初の宣言の後、修正されたためです-一方、入力パラメーターを述語に変更できることを望んでいましたすべてのループ。

以下のタスクは、開始日、それに続く終了日、それに続く開始日、最後の後の終了日などを選択しようとします。オーバーラップします。開始日はあるリストから取得され、終了日は別のリストから取得されます。

次の解決策は、「過去dropwhile」にある日付を渡すために使用して、開始日をループし、次に終了日をループします。初めてでも完璧に機能します。しかし、2 回目のパスでは、終了日が '2009-12-14' でスタックします。「isbefore」ルーチンを分割したのは、いつテストされ、いつテストされないかを確認できるようにするためです。確かではありませんが、最初のパスでテスト全体が固定され、各パスで再コンパイルされないことが起こっていると思いますか? 私が望んでいた/期待していたように。dropwhile

while True最後に、すべてを a 内にラップし、例外を介して終了して、StopIteration間隔の完全なシーケンスを抽出することを望んでいました。しかし、それは決して発火しません。私が試したとき、どちらのイテレータも実際には最後まで「次へ」なりませんでした。

質問

  1. 何が起きているかというと、それは (決まった結論) 正しいのでしょうか?
  2. 私が望んでいたように動作させるための短くてきれいでエレガントな方法はありますか? 自分の好きなように動作する独自の dropwhile を作成する必要がありますか?

コード

import itertools
import datetime

startdates = [
    datetime.date(2009, 11, 5), datetime.date(2009, 11, 13),
    datetime.date(2009, 12, 4), datetime.date(2009, 12, 7),
    datetime.date(2009, 12, 29), datetime.date(2009, 12, 30)]

enddates = [
    datetime.date(2009, 10, 1), datetime.date(2009, 10, 2),
    datetime.date(2009, 11, 4), datetime.date(2009, 12, 14),
    datetime.date(2009, 12, 15),datetime.date(2009, 12, 30)]

enddate = datetime.date(1900, 1, 1)
startdate = datetime.date(1900, 1, 1)

def isbefore(a, b):
    return a <= b

for startdate in itertools.dropwhile(lambda date: isbefore(date, enddate), startdates):
    for enddate in itertools.dropwhile(lambda date: isbefore(date, startdate), enddates):
        print startdate, enddate
        break

電流出力

2009-11-05 2009-12-14
2009-11-13 2009-12-14
2009-12-04 2009-12-14
2009-12-07 2009-12-14

望ましい出力

2009-11-05 2009-12-14
2009-12-29 2009-12-30

より注意深いタイプは、私が昨日この質問をしたことに気付くでしょうが、それは同じ問題を提示しますが、それは一般的な解決策を必要としますが、今回は具体的にdropwhileの仕組みについて尋ねています.

4

1 に答える 1

4

述語を満たすアイテムを削除するとdropwhile、変更されていない残りの iterable が生成されます。代わりに使用itertools.ifilterfalseすると、最初の実行後も述語の処理が続行されるため、目的の出力が得られます。

于 2012-08-25T05:39:02.473 に答える