Organize a list of unique integers and create ranges/summaries when possible
<p>I am trying to setup a function or a class to store unique integers with abilities to add,remove or check for existence. This of course can be easily achieved using normal set. The tricky part here is displaying of ranges. I mean, if I have all the numbers between 100 and 20000 I don't want to display a huge list all the numbers in between, but rather displaying 100-20000. </p>

<p>Consider the following example:</p>

<pre><code>numbers 3000,3008-3015,3020,3022,3030-3043,3068
</code></pre>

<p>The goal is to create a function or class to add, check or retrieve information about current numbers. Here is how I imagine this: </p>

<pre><code>&gt;&gt;&gt; f_check(3016) 
False
&gt;&gt;&gt; f_check(3039)
True
&gt;&gt;&gt; f_add(3016)
3000,3008-3016,3020,3022,3030-3043,3068
&gt;&gt;&gt; f_remove(3039)
3000,3008-3016,3020,3022,3030-3038,3040-3043,3068    
&gt;&gt;&gt; f_add(3100)
3000,3008-3016,3020,3022,3030-3038,3040-3043,3068,3100
</code></pre>

<p>and so forth... </p>

<p>Again, pay attention to the range part (3030-3038, 3040-3043) etc. I don't want to display every single entry for the consecutive numbers but rather displaying a "summary" or range. </p>

<p>Using the same example again, if I add 3021, I'll expect the following result:</p>

<pre><code>&gt;&gt;&gt; f_add(3021)
3000,3008-3016,3020-3022,3030-3043,3068
</code></pre>

<p>Many thanks in advance for your thoughts!</p>

<p>As people in the comments say, most of your operations are simple list operation. However, if your data contains ranges (e.g. 3008-3015), it then becomes a different story. The reason is that you need some sort of decoding to what that range means.
I wrote a simple code using only functions (no classes) that will do just that.</p>

<pre><code>matched = False
</code></pre>

<p>Check whether a number or a range:</p>

<pre><code>def valueCheck(val):
    if "-" in val:
        return False
    else:
        return True
</code></pre>

<p>Encode the range into two values (start, end)</p>

<pre><code>def rangeCheck(val):
    if valueCheck(val):
        return val, val
    else:
        return val.split("-")
</code></pre>

<p>Check whether a number matches the content of a list:</p>

<pre><code>def f_check(new_number, numbers_list):
    global matched
    for i in numbers_list:
        rangeCheck(i)
        if int(rangeCheck(i)[0]) &lt;= int(new_number) &lt;= int(rangeCheck(i)[1]):
            print "{} matches {}".format(new_number, i)
            matched = True
            break
    if not matched:
        print "{} doesn't exist in your list".format(new_number)
</code></pre>

<p>Add a number to the list:</p>

<pre><code>def f_add(new_number, numbers_list):
    numbers_list.append(new_number)
    print numbers_list
</code></pre>

<p>Delete a number from the list:</p>

<pre><code>def f_delete(new_number, numbers_list):
    numbers_list.remove(new_number)
    print numbers_list
</code></pre>

<p>Assuming your numbers are string values in a list like so:</p>

<pre><code>numbers = ["3000", "3008-3015", "3020", "3022", "3030-3043", "3068"]
</code></pre>

<p>No match:</p>

<pre><code>f_check("2000", numbers)
2000 doesn't exist in your list
</code></pre>

<p>Single match:</p>

<pre><code>f_check("3020", numbers)
3020 matches 3020
</code></pre>

<p>Range match:</p>

<pre><code>f_check("3010", numbers)
3010 matches 3008-3015
</code></pre>

<p>Other simple operations:
Add:</p>

<pre><code>f_add("2000", numbers)
['3000', '3008-3015', '3020', '3022', '3030-3043', '3068', '2000']
</code></pre>

<p>Delete:</p>

<pre><code>f_delete("3068", numbers)
['3000', '3008-3015', '3020', '3022', '3030-3043']
</code></pre>

<p>Please note that single match can also be done much easier by using the following:</p>

<pre><code>number = "3020"
if number in numbers:
    print "{} matched".format(number)
3020 matched
</code></pre>

<hr>

<p><strong>UPDATE #1</strong></p>

<hr>

<p>To overcome your raised "problem" of adding number to existing ranges and/or making new range if needed. I found a similar question here <a href="http://stackoverflow.com/questions/2154249/identify-groups-of-continuous-numbers-in-a-list">How to group list of continuous values in ranges</a>, which can solve part of your issue. However, your original encoding (val-val) isn't going to be helpful in this case.
To solve this, you can do the following:</p>

<p><strong>Step 1</strong>, comment these two lines:</p>

<pre><code># rangeCheck(i)
# if int(rangeCheck(i)[0]) &lt;= int(new_number) &lt;= int(rangeCheck(i)[1]):
"""
you will not be using the rangeCheck() or valueCheck() anymore.
"""
</code></pre>

<p><strong>Step 2</strong>, add this line instead of the original IF-statement:</p>

<pre><code>if int(i[0]) &lt;= int(new_number) &lt;= int(i[1]):
</code></pre>

<p><strong>Step 3</strong>, add this function which will flatten your list of numbers</p>

<pre><code>def flatList(numbers_list):
    for i in numbers_list:
        if len(str(i).split("-")) &gt; 1:
            numbers_list.extend(range(int(i.split("-")[0]), int(i.split("-")[1]) + 1))
            numbers_list.remove(i)
    return numbers_list
</code></pre>

<p><strong>Step 4</strong>, add this function (taken from <a href="http://stackoverflow.com/questions/2154249/identify-groups-of-continuous-numbers-in-a-list">1</a>) which will group your flat list into ranges of values</p>

<pre><code>from operator import itemgetter
from itertools import groupby
def numbers_group(flatt_list):
    flatt_list = [int(i) for i in flatt_list]
    ranges = []
    for k, g in groupby(enumerate(flatt_list), lambda (i, x): i - x):
        group = map(itemgetter(1), g)
        ranges.append((group[0], group[-1]))
    return ranges
</code></pre>

<p><strong>Usage:</strong></p>

<pre><code>numbers = ["3000", "3008-3015", "3020", "3022", "3030-3043", "3068"]

print flatList(numbers)
['3000', '3020', '3022', '3068', 3008, 3009, 3010, 3011, 3012, 3013, 3014, 3015, 3030, 3031, 3032, 3033, 3034, 3035, 3036, 3037, 3038, 3039, 3040, 3041, 3042, 3043]

print numbers_group(sorted(flatList(numbers)))
[(3008, 3015), (3030, 3043), (3000, 3000), (3020, 3020), (3022, 3022), (3068, 3068)]

numbers = f_add("3021", numbers)
print numbers_group(sorted(flatList(numbers)))
[(3008, 3015), (3030, 3043), (3000, 3000), (3020, 3022), (3068, 3068)]

numbers = f_delete("3021", numbers)
print numbers_group(sorted(flatList(numbers)))
[(3008, 3015), (3030, 3043), (3000, 3000), (3020, 3020), (3022, 3022), (3068, 3068)]
</code></pre>

python integer set