我想出了一個巧妙的解決我的問題,但不那麼狡猾,它不工作: -/
後點擊通過調試的時間我認爲 ,所以也許你可以驗證這一點,它不起作用的原因是因爲itertools.dropwhile
,在初始聲明後,是固定的 - 而我希望我可以在每個循環上改變輸入參數到謂詞。
下面的任務試圖選擇一個startdate,然後是一個跟隨它的enddate,接着是startdate,最後一個是enddate,等等,這樣我們就得到一系列日期不重疊的區間。起點來自一個列表,而來自另一個列表的終點。
以下解決方案在開始日期和結束日期之間循環,使用dropwhile
來覆蓋'過去'的日期。它通過第一次完美運作。但在第二次傳遞中,enddate卡在'2009-12-14'。我爆發了「isbefore」例程,以便我能夠看到它什麼時候被測試,什麼時候沒有。不確定,但我認爲現在發生的情況是,整個測試在第一次通過時就會被設置爲一成不變,並且不會在每次通過時重新編譯自身?就像我希望/預期的那樣。
爲了完成它,我希望將它全部包裝在while True
中,並通過StopIteration
異常退出,從而提取完整的區間序列。但它永遠不會開火。當我嘗試迭代器時,實際上'下一個'一直到最後。
問題
- 那是(對集多功能於石結論)正確的,什麼是怎麼回事?
- 是否有一種簡潔,乾淨,優雅的方式讓它按照我希望的方式行事?我是否必須自己寫下自己想要的行爲?
代碼
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
更注重細節的類型會注意到昨天我問了this question,它提出了同樣的問題,但是那個需要一個通用的解決方案,而這次我正在具體詢問dropwhile的工作方式。
在您發佈您意識到某件重要的事情後,總是會立即發現它:在循環中得到修復 - 我試圖改變它啓動後的迭代器!? –
我希望我不是在說明顯而易見的,但是你以一種令人困惑的方式重用'startdate'和'enddate',不是嗎?我也得到了不同的輸出。 –
顯然,開始日期和結束日期一直在變化。這是否構成問題?爲拉姆達?我可以通過將它們喂入像isbefore這樣的例程來解決這些問題嗎?我看不到如何創建一個不使用lambda而使用該值的dropwhile謂詞? –