我有日期对象的词典列表:
{ "begin" :date object1, "end" : date object2 }
....
{ "begin" :date object3, "end" : date object4 }
我希望按条件简化此列表:
if cur.end == next.begin - datetime.timedelta(seconds=1))
cur.end = next.end
delete next
怎么做?
答案 0 :(得分:1)
我使用整数而不是datetime对象来保持代码简单,但根据您的需要更改它是微不足道的。 在迭代它时从集合中删除项将破坏迭代器,因此您要么使用第二个列表(可能是内存密集型),要么替换元素而不是删除它们。由于你的元素是字典,我认为用None替换要删除的元素是安全的,最后只过滤掉Nones。
l=[
{ "b" : 1, "e" : 2},
{ "b" : 3, "e" : 5},
{ "b" : 6, "e" : 7},
{ "b" : 10, "e" : 12},
{ "b" : 13, "e" : 20}
]
for i in xrange(len(l) - 1):
cur = l[i]
if not cur:
continue
next = l[i + 1]
if cur["e"] == next["b"] - 1:
cur["e"] = next["e"]
l[i+1] = None
l = filter(None, l)
print l
由于第一个版本无法完全满足您的需求,请重复这些步骤,直到不再合并时间间隔为止。 这是效率低下的,可能是当今最无法使用的代码,但它可以完成这项工作。
changed = True
while changed:
changed = False
l = filter(None, l)
for i in xrange(len(l) - 1):
cur = l[i]
if cur is None:
continue
next = l[i + 1]
if cur["e"] == next["b"] - 1:
cur["e"] = next["e"]
l[i+1] = None
changed = True
l = filter(None, l)
print l
答案 1 :(得分:1)
就像在另一个答案中解释的那样,你不应该在迭代它时从列表中删除一个元素,它可能会导致很多问题。另一种创建全新列表的方法是 -
import datetime
lisdic = [] #list of dictionaries
prev = None
result = []
for i in lisdic:
if not prev:
prev = i
elif prev['end'] == i['begin'] - datetime.timedelta(seconds=1):
prev['end'] = i['end']
else:
result.append(prev)
prev = i
if prev:
result.append(prev)
这也可以处理多个词典中的类似区间(下面的例子是DEMO列表中的前三个词典)。
演示 -
>>> import datetime
>>> lisdic = [{"begin":datetime.datetime(2015,10,2,10,0,0),"end":datetime.datetime(2015,10,2,10,30,0)},
... {"begin":datetime.datetime(2015,10,2,10,30,1),"end":datetime.datetime(2015,10,2,11,0,0)},
... {"begin":datetime.datetime(2015,10,2,11,0,1),"end":datetime.datetime(2015,10,2,12,0,0)},
... {"begin":datetime.datetime(2015,10,3,10,0,0),"end":datetime.datetime(2015,10,3,10,30,0)},
... {"begin":datetime.datetime(2015,10,3,11,0,0),"end":datetime.datetime(2015,10,3,11,30,0)},
... {"begin":datetime.datetime(2015,10,4,12,0,0),"end":datetime.datetime(2015,10,2,12,10,0)}]
>>> prev = None
>>> result = []
>>> for i in lisdic:
... if not prev:
... prev = i
... elif prev['end'] == i['begin'] - datetime.timedelta(seconds=1):
... prev['end'] = i['end']
... else:
... result.append(prev)
... prev = i
...
>>>
>>> if prev:
... result.append(prev)
...
>>> pprint.pprint(result)
[{'begin': datetime.datetime(2015, 10, 2, 10, 0),
'end': datetime.datetime(2015, 10, 2, 12, 0)},
{'begin': datetime.datetime(2015, 10, 3, 10, 0),
'end': datetime.datetime(2015, 10, 3, 10, 30)},
{'begin': datetime.datetime(2015, 10, 3, 11, 0),
'end': datetime.datetime(2015, 10, 3, 11, 30)},
{'begin': datetime.datetime(2015, 10, 4, 12, 0),
'end': datetime.datetime(2015, 10, 2, 12, 10)}]