pythonic way to find separate integer intervals in dictionary integer mapping
<p>I have a dictionary mapping one integer range onto another, as an example:</p>

<pre><code>data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8}
</code></pre>

<p>I want to find all regions where the numeric intervals in the values fail to increment, so my output should be:</p>

<pre><code>result = [[6, 8]]
</code></pre>

<p>For the above input.</p>

<p>I think my answer will involve the grouping itertools recipe described <a href="https://docs.python.org/2.6/library/itertools.html#examples" rel="nofollow">here</a>. I tried to do a simple implementation of it for my purposes, but I am unsure how to transform the results into my desired result:</p>

<pre><code>from operator import itemgetter
from itertools import groupby
data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8}
for k, pos in groupby(enumerate(data.iteritems()), lambda (i, (a, s)):i - s):
    print map(itemgetter(1), pos)
</code></pre>

<p>Has the output:</p>

<pre><code>[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6)]
[(7, 6)]
[(8, 6), (9, 7), (10, 8)]
</code></pre>

<p>Which properly groups my input data, but does not really give me the interval I want. The challenge I see in parsing this output to the interval I want is that it is giving me an interval for the 'skip region'.</p>

<p>Assuming that the "non-increasing" values remain constant in those regions and do not decrease either, you can just group entries that have the same value and then pick those groups that have more than one entry. Finally, extract the beginning and the end index.</p>

<pre><code>&gt;&gt;&gt; data = {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 6, 8: 6, 9: 7, 10: 8}
&gt;&gt;&gt; items = sorted(data.items())
&gt;&gt;&gt; groups = itertools.groupby(items, key=operator.itemgetter(1))
&gt;&gt;&gt; ranges = [grp for grp in (list(grp) for key, grp in groups) if len(grp) &gt; 1]
&gt;&gt;&gt; ranges
[[(6, 6), (7, 6), (8, 6)]]
&gt;&gt;&gt; [(r[0][0], r[-1][0]) for r in ranges]
[(6, 8)]
</code></pre>

python