Python list of dictionaries: Get last item of each day
<p>I have a list of dictionaries, ordered by the key <code>date</code>:</p>

<pre><code>d = [{'date': datetime.strptime('2016-01-01 07:00', "%Y-%m-%d %H:%M"), 'val': 1},
{'date': datetime.strptime('2016-01-01 23:00', "%Y-%m-%d %H:%M"), 'val': 3},
{'date': datetime.strptime('2016-01-02 07:00', "%Y-%m-%d %H:%M"), 'val': 5},
{'date': datetime.strptime('2016-01-02 22:13', "%Y-%m-%d %H:%M"), 'val': 7},
{'date': datetime.strptime('2016-01-02 23:00', "%Y-%m-%d %H:%M"), 'val': 9},
{'date': datetime.strptime('2016-01-03 00:10', "%Y-%m-%d %H:%M"), 'val': 17},
{'date': datetime.strptime('2016-01-03 09:12', "%Y-%m-%d %H:%M"), 'val': 25},
{'date': datetime.strptime('2016-01-03 21:52', "%Y-%m-%d %H:%M"), 'val': 37}]
</code></pre>

<p>And i want to get the last(latest) item of each day, so in this case it would be:</p>

<pre><code>{'date': datetime.strptime('2016-01-01 23:00', "%Y-%m-%d %H:%M"), 'val': 3},
{'date': datetime.strptime('2016-01-02 23:00', "%Y-%m-%d %H:%M"), 'val': 9},
{'date': datetime.strptime('2016-01-03 21:52', "%Y-%m-%d %H:%M"), 'val': 37},
</code></pre>

<p>I have the following piece of code which does the trick:</p>

<pre><code>previous_item = None
wanted_data = []
for index, entry in enumerate(d):
    if not previous_item:
        previous_item = entry
        continue
    if entry['date'].date() != previous_item['date'].date():
        wanted_data.append(previous_item)
    previous_item = entry

    #Add as well the last item
    if index + 1 == len(d):
        wanted_data.append(entry)
</code></pre>

<p>But i believe there are better and faster ways to do it... Besides, thats pretty ugly.</p>

<p>Is there a more pythonish way to achieve this?</p>

<p>Thanks!</p>

<p>Assuming that the data is already sorted by <code>'date'</code> (it seems to be in your case), you can use <a href="https://docs.python.org/3.5/library/itertools.html#itertools.groupby" rel="nofollow"><code>itertools.groupby</code></a> to group by the <code>date()</code>, and then get the last item from each group.</p>

<pre><code>&gt;&gt;&gt; d = sorted(d, key=lambda x: x["date"])  # only if not already sorted
&gt;&gt;&gt; groups = itertools.groupby(d, lambda x: x["date"].date())
&gt;&gt;&gt; wanted_data = [list(grp)[-1] for key, grp in groups]
&gt;&gt;&gt; wanted_data
[{'date': datetime.datetime(2016, 1, 1, 23, 0), 'val': 3},
 {'date': datetime.datetime(2016, 1, 2, 23, 0), 'val': 9},
 {'date': datetime.datetime(2016, 1, 3, 21, 52), 'val': 37}]
</code></pre>

<p>Note that this will expand each of the groups into a <code>list</code>. If this is too expensive, because there are very many entries for each date, you could create a function to get the last entry from an iterator, e.g. using <code>reduce</code> (or <code>functools.reduce</code> in Python 3):</p>

<pre><code>&gt;&gt;&gt; last = lambda x: functools.reduce(lambda x, y: y, x)
&gt;&gt;&gt; wanted_data = [last(grp) for key, grp in groups]
</code></pre>

python