【发布时间】:2012-02-06 17:39:57
【问题描述】:
从my previous question 开始,我现在正在读取两个文件 A 和 B,并将 2009 年的日期放入 AB2 对象列表 (subAB) 中的第一个非 2009 行中。
class AB2(object):
def __init__(self, datetime, a=False, b=False):
self.datetime = datetime
self.a = a
self.b = b
self.subAB = []
例如:
file A: 20111225, 20111226, 20090101
file B: 20111225, 20111226, 20090101, 20090102, 20111227, 20090105
应导致:(方括号显示 subAB 列表)
AB2(20111225, a = true, b = true, [])
AB2(20111226, a = true, b = true,
[AB2(20090101, a = true, b = true, []),
AB2(20090102, a = false, b = true, [])],
AB2(20111227, a = false, b = true,
[AB2(20090105, a = false, b = true)])
不幸的是,这使之前的解决方案变得复杂:
list_of_objects = [(i, i in A, i in B) for i in set(A) | set(B)]
因为:
顺序很重要(2009 年项目进入文件中第一个 2011 年项目)
文件中可以有多个相同日期时间的项目
现在也对 subAB 对象列表感兴趣
由于这些原因,我们不能使用当前存在的 set(因为它会删除重复项并丢失顺序)。我已经探索过使用OrderedSet recipe,但我想不出在这里应用它的方法。
我当前的代码:
listA = open_and_parse(file A) # list of parsed dates
listAObjects = [AB2(dt, True, None) for dt in listA] # list of AB2 Objects from list A
nested_listAObjects = nest(listAObjects) # puts 2009 objects into 2011 ones
<same for file B>
return combine(nested_listAObjects, nested_listBObjects)
嵌套方法:(将 2009 项放入前一个 2011 项中。如果 2009 项位于文件开头,则忽略它们)
def nest(list):
previous = None
for item in list:
if item.datetime.year <= 2009:
if previous is not None:
previous.subAB.append(item)
else:
previous = item
return [item for item in list if item.datetime.year > 2009]
但我有点卡在combine 函数上:
def combine(nestedA, nestedB):
combined = nestedA + nestedB
combined.sort(key=lambda x: x.datetime)
<magic>
return combined
此时,如果没有魔法,combined 将如下所示:
AB2(20111225, a = true, b = None, []) # \
AB2(20111225, a = None, b = true, []) # / these two should merge to AB2(20111225, a = true, b = true, [])
AB2(20111226, a = true, b = None,
[AB2(20090101, a = true, b = None, []),
AB2(20090102, a = true, b = None, [])],
AB2(20111226, a = None, b = true,
[AB2(20090101, a = None, b = true, [])],
# The above two lines should combine, and so should their subAB lists (but only recurse to that level, not infinitely)
AB2(20111227, a = None, b = true,
[AB2(20090105, a = None, b = true)])
我希望我可以发布一个新问题 - 这将是一个与我之前的问题完全不同的解决方案。也很抱歉这篇长文,我认为最好解释一下我正在做的所有事情,这样你才能完全理解问题,也许可以为整个问题提供替代解决方案,而不仅仅是combine 方法.谢谢!
编辑:澄清:
基本上,我正在检查来自两台已连接计算机的日志,并比较它们是在特定时间关闭,还是只关闭一台。如果计算机在检索到真正的 2012 时间之前重置,则计算机在 2009 时间启动(但并非总是在 1 月 1 日 - 有时是 1 月 4 日等)。因此,我试图将随后的 2009 年关闭与之前的关闭联系起来,以便我知道它何时会快速重置。
2011/2012 年的日期应该排序,但 2009 年的日期不是。一台计算机的日志文件(在我的示例中为fileA)可能如下所示:
2011/12/15
2011/12/17
2011/12/19 # Something goes wrong, and causes the computer to reset 5 times rapidly
2009/01/01
2009/01/01
2009/01/04
2009/01/01
2011/12/20 # And everything is better again
2011/12/25
实际上,它们实际上是日期时间(例如2009/01/01 01:57:01),所以我可以简单地比较两个日期时间是否在某个timedelta 内。
我正在寻求一种更简洁的整体解决方案/方法,或者是针对将这两个 AB2 对象列表结合起来的问题的特定解决方案。
将两者结合起来最简单的方法是遍历已排序的组合列表(已将 2009 个对象放入其父项中),比较下一项是否与当前项的日期相同,并从中创建一个新列表项目。
【问题讨论】:
-
我不清楚您要如何匹配 A 和 B 中的日期。文件未排序,但所有非 2009 日期是否按升序出现?非 2009 年的日期可以多次出现吗?
-
我希望我可以发布一个新问题 - 当这是一个新问题时,发布一个新问题是正确的做法。
-
@JanneKarila 对不起,不清楚,我会编辑澄清。
标签: python list datetime recursion merge