"Compressing" a list of integers
<p>I have a list of integers as follows:</p>

<pre><code>my_list = [2,2,2,2,3,4,2,2,4,4,3]
</code></pre>

<p>What I want is to have this as a list os strings, indexed and 'compressed', that is, with each element indicated by its position in the list and with each successive duplicate element indicated as a range, like this:</p>

<pre><code>my_new_list = ['0-3,2', '4,3', '5,4', '6-7,2', '8-9,4', '10,3']
</code></pre>

<p>EDIT: The expected output should indicate that list elements 0 to 3 have the number 2, element 3, the number 3, element 5, the number 4, elements 6 and 7, the number 2, elements 8 and 9, number 4, and element 10, number 3. </p>

<p>EDIT 2: The output list need not (indeed cannot) be a list of integers, but a list of strings instead.</p>

<p>I could find many examples of finding (and deleting) duplicated elements from lists, but nothing along the lines of what I need.</p>

<p>Could someone point out a relevant example or suggest an algorithm for solving this?</p>

<p>Thanks in advance!</p>

<p>Here is a lazy version that works on any sequence, and yields slices. Thus it's generic and memory efficient.</p>

<pre><code>def compress(seq):
    start_index = 0
    previous = None
    n = 0
    for i, x in enumerate(seq):
        if previous and x != previous:
            yield previous, slice(start_index, i)
            start_index = i

        previous = x
        n += 1
    if previous:
        yield previous, slice(start_index, n)
</code></pre>

<p>Usage :</p>

<pre><code>assert list(compress([2, 2, 2, 2, 3, 4, 2, 2, 4, 4, 3])) == [
    (2, slice(0, 4)),
    (3, slice(4, 5)),
    (4, slice(5, 6)),
    (2, slice(6, 8)),
    (4, slice(8, 10)),
    (3, slice(10, 11)),
]
</code></pre>

<p>Why slices? Because it's convenient (can be used as-is for indexing) and the semantics (upper bound not included) are more "standard". Changing that to tuples or string with upper bound is easy btw.</p>

python list