Applying lambda function to datetime
<p>I am using the following code to find clusters with difference &lt;=1 in a list </p>

<pre><code>from itertools import groupby
from operator import itemgetter
data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
for k, g in groupby(enumerate(data), lambda (i, x): (i-x)):
    print map(itemgetter(1), g)
</code></pre>

<p>If however I change the <code>data</code> to be an array of datetime to find cluster of datetimes which are only 1 hour apart, it fails.</p>

<p>I am trying the following:</p>

<pre><code>&gt;&gt;&gt; data
array([datetime.datetime(2016, 10, 1, 8, 0),
       datetime.datetime(2016, 10, 1, 9, 0),
       datetime.datetime(2016, 10, 1, 10, 0), ...,
       datetime.datetime(2019, 1, 3, 9, 0),
       datetime.datetime(2019, 1, 3, 10, 0),
       datetime.datetime(2019, 1, 3, 11, 0)], dtype=object)

    from itertools import groupby
    from operator import itemgetter
    data = [ 1, 4,5,6, 10, 15,16,17,18, 22, 25,26,27,28]
    for k, g in groupby(enumerate(data), lambda (i, x): (i-x).total_seconds()/3600):
        print map(itemgetter(1), g)
</code></pre>

<p>The error is:</p>

<pre><code>    for k, g in groupby(enumerate(data), lambda (i, x): int((i-x).total_seconds()/3600)):
TypeError: unsupported operand type(s) for -: 'int' and 'datetime.datetime'
</code></pre>

<p>There are lot of solutions on the web but I want to apply this particular one for learning.</p>

<p>If you want to get all subsequences of items such that each item is an hour later than the previous one (not clusters of items that each are within an hour from eachother), you need to iterate over pairs <code>(data[i-1], data[i])</code>. Currently, you are just iterating over <code>(i, data[i])</code> which raises <code>TypeError</code> when you try to substract <code>data[i]</code> from <code>i</code>. A working example could look like this:</p>

<pre><code>from itertools import izip

def find_subsequences(data):
    if len(data) &lt;= 1:
        return []

    current_group = [data[0]]
    delta = 3600
    results = []

    for current, next in izip(data, data[1:]):
        if abs((next - current).total_seconds()) &gt; delta:
            # Here, `current` is the last item of the previous subsequence
            # and `next` is the first item of the next subsequence.
            if len(current_group) &gt;= 2:
                results.append(current_group)

            current_group = [next]
            continue

        current_group.append(next)

    return results
</code></pre>

python lambda