2012-08-25 60 views
2

介绍'dropwhile'是静态的吗?我可以使它动态吗?

我想出了一个巧妙的解决我的问题,但不那么狡猾,它不工作: -/

后点击通过调试的时间我认为 ,所以也许你可以验证这一点,它不起作用的原因是因为itertools.dropwhile,在初始声明后,是固定的 - 而我希望我可以在每个循环上改变输入参数到谓词。

下面的任务试图选择一个startdate,然后是一个跟随它的enddate,接着是startdate,最后一个是enddate,等等,这样我们就得到一系列日期不重叠的区间。起点来自一个列表,而来自另一个列表的终点。

以下解决方案在开始日期和结束日期之间循环,使用dropwhile来覆盖'过去'的日期。它通过第一次完美运作。但在第二次传递中,enddate卡在'2009-12-14'。我爆发了“isbefore”例程,以便我能够看到它什么时候被测试,什么时候没有。不确定,但我认为现在发生的情况是,整个测试在第一次通过时就会被设置为一成不变,并且不会在每次通过时重新编译自身?就像我希望/预期的那样。

为了完成它,我希望将它全部包装在while True中,并通过StopIteration异常退出,从而提取完整的区间序列。但它永远不会开火。当我尝试迭代器时,实际上'下一个'一直到最后。

问题

  1. 那是(对集多功能于石结论)正确的,什么是怎么回事?
  2. 是否有一种简洁,干净,优雅的方式让它按照我希望的方式行事?我是否必须自己写下自己想要的行为?

代码

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的工作方式。

+0

在您发布您意识到某件重要的事情后,总是会立即发现它:在循环中得到修复 - 我试图改变它启动后的迭代器!? –

+1

我希望我不是在说明显而易见的,但是你以一种令人困惑的方式重用'startdate'和'enddate',不是吗?我也得到了不同的输出。 –

+0

显然,开始日期和结束日期一直在变化。这是否构成问题?为拉姆达?我可以通过将它们喂入像isbefore这样的例程来解决这些问题吗?我看不到如何创建一个不使用lambda而使用该值的dropwhile谓词? –

回答

4

一旦dropwhile已经删除满足谓词的条目,它会产生未修改迭代的剩余部分。在其位置使用itertools.ifilterfalse可以提供所需的输出,因为即使在初始运行后,它也会继续处理谓词。

+0

哇。这确实有用。谢谢。 –

+2

或者他可以简单地使用genexp。 – Bakuriu

+0

在这个例子中,我实际上能够找到一个完全不需要itertools(或genexp)的解决方案;但是这有效,让我在那里,并回答了这个问题。蜱。 –

相关问题