Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to simplify list of dictionaries by condition?

I have list of dictionaries of date objects:

{ "begin" :date object1, "end" : date object2 }
....
{ "begin" :date object3, "end" : date object4 }

I want to simplify this list by condition:

if cur.end == next.begin - datetime.timedelta(seconds=1))
    cur.end = next.end
    delete next

How to do it ?

like image 886
Bdfy Avatar asked Oct 02 '15 10:10

Bdfy


People also ask

How do I sort a list of dictionaries by value?

To sort a list of dictionaries according to the value of the specific key, specify the key parameter of the sort() method or the sorted() function. By specifying a function to be applied to each element of the list, it is sorted according to the result of that function.

Can == operator be used on dictionaries?

According to the python doc, you can indeed use the == operator on dictionaries.

How do I convert a list of dictionaries in Python?

Since python dictionary is unordered, the output can be in any order. To convert a list to dictionary, we can use list comprehension and make a key:value pair of consecutive elements. Finally, typecase the list to dict type.


1 Answers

Like explained in the other answer, you should not delete an element from a list while iterating over it, it can lead to lots of issues. Another method that creates a completely new list would be -

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)

This would also handle similar intervals across multiple dictionaries (an Example being the first 3 dictionaries in the list in DEMO below).

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)}]
like image 58
Anand S Kumar Avatar answered Nov 29 '22 19:11

Anand S Kumar