【问题标题】:Is 'dropwhile' static? can I make it dynamic?'dropwhile' 是静态的吗?我可以让它动态吗?
【发布时间】:2012-08-25 05:24:13
【问题描述】:

简介

我想出了一个巧妙的解决方案来解决我的问题,但并不那么巧妙,它不起作用:-/

在我认为点击调试器数小时后,也许您可​​以验证这一点,它不起作用的原因是因为itertools.dropwhile,在初始声明之后,是固定的 - 而我希望我可以在每个循环中更改谓词的输入参数。

下面的任务尝试选择一个开始日期,然后是其后的结束日期,然后是其后的开始日期,最后一个之后的结束日期......等等,所以我们最终得到一系列日期间隔不重叠。 startdates 来自一个列表,enddates 来自另一个列表。

以下解决方案循环遍历开始日期,然后遍历结束日期,使用 dropwhile 传递“过去”中的日期。它在第一次通过时完美运行。但在第二次通过时,结束日期卡在“2009-12-14”。我打破了“isbefore”例程,以便我可以看到它什么时候被测试,什么时候没有。不确定,但我认为正在发生的事情是整个dropwhile 测试在第一遍就固定下来了,并且在每次通过时都不会重新编译自己?就像我希望/预期的那样。

为了完成它,我希望将它全部包装在 while True 中并通过 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

更多细心的人会注意到我昨天问过this question,它提出了同样的问题,但需要一个通用的解决方案,而这次我专门询问 dropwhile 的工作原理。

【问题讨论】:

  • 它总是在您发布后立即意识到一些重要的事情:也许它的 for..in 循环得到修复 - 我试图在它启动后更改它的迭代器!?
  • 我希望我不是在说显而易见的事情,但是您以一种令人困惑的方式重复使用 startdateenddate,不是吗?我也得到了与你不同的输出。
  • 显然 startdate 和 enddate 一直在变化。这会造成问题吗?对于拉姆达?我可以通过将这些问题输入到 isbefore 之类的例程中来分离这些问题吗?我看不到如何在不使用 lambda 的情况下为 dropwhile 创建一个消耗值的谓词?

标签: python itertools


【解决方案1】:

一旦dropwhile 删除了满足谓词的项目,它就会产生未修改的其余可迭代项。使用 itertools.ifilterfalse 代替它会提供您想要的输出,因为即使在初始运行之后它也会继续处理谓词。

【讨论】:

  • 或者他可以简单地使用一个 genexp。
  • 在这个例子中,我实际上能够找到一个根本不需要 itertools(或 genexp)的解决方案;但这有效,让我到了那里,并回答了这个问题。打勾。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-04-09
  • 2019-09-12
  • 1970-01-01
  • 1970-01-01
  • 2017-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多