Note that there are some explanatory texts on larger screens.

plurals
  1. POConvert List of Numbers to String Ranges
    primarykey
    data
    text
    <p>I'd like to know if there is a simple (or already created) way of doing the opposite of this: <a href="http://code.activestate.com/recipes/577279-generate-list-of-numbers-from-hyphenated-and-comma/" rel="nofollow noreferrer">Generate List of Numbers from Hyphenated...</a>. This link could be used to do:</p> <pre><code>&gt;&gt; list(hyphen_range('1-9,12,15-20,23')) [1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 23]: </code></pre> <p>I'm looking to do the opposite (note that 10 and 21 are included so it would be compatible with the range function, where range(1,10)=[1,2,3,4,5,6,7,8,9]):</p> <pre><code>&gt;&gt; list_to_ranges([1, 2, 3, 4, 5, 6, 7, 8, 9, 12, 15, 16, 17, 18, 19, 20, 23]) '1-10,12,15-21,23' </code></pre> <p>Eventually, I would like to have the output also incorporate a step where the last number of the output indicates the step:</p> <pre><code>&gt;&gt; list_to_ranges([1, 3, 5, 7, 8, 9, 10, 11]) '1-13:2,8,10' </code></pre> <p>Essentially, this would end up being kind of like an "inverse" range function</p> <pre><code>&gt;&gt; tmp = list_to_ranges([1, 3, 5]) &gt;&gt; print tmp '1-7:2' &gt;&gt; range(1, 7, 2) [1, 3, 5] </code></pre> <p>My guess is that there is no really easy/simple way to do this, but I thought I would ask on here before I go make some brute force, long method.</p> <p><strong>EDIT</strong></p> <p>Using the code from an answer to <a href="https://stackoverflow.com/questions/3149440/python-splitting-list-based-on-missing-numbers-in-a-sequence">this post</a> as an example, I came up with a simple way to do the first part. But I think that identifying the patterns to do steps would be a bit harder.</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] print data, '\n' str_list = [] for k, g in groupby(enumerate(data), lambda (i,x):i-x): ilist = map(itemgetter(1), g) print ilist if len(ilist) &gt; 1: str_list.append('%d-%d' % (ilist[0], ilist[-1]+1)) else: str_list.append('%d' % ilist[0]) print '\n', ','.join(str_list) </code></pre> <p><strong>EDIT 2</strong></p> <p>Here is my attempt at including the step size...it is pretty close, but the first numbers get repeated. I think that with a little bit of tweaking of this, it will be close to what I want - or at least good enough.</p> <pre><code>import numpy as np from itertools import groupby def list_to_ranges(data): data = sorted(data) diff_data = np.diff(data).tolist() ranges = [] i = 0 for k, iterable in groupby(diff_data, None): rng = list(iterable) step = rng[0] if len(rng) == 1: ranges.append('%d' % data[i]) elif step == 1: ranges.append('%d-%d' % (data[i], data[i+len(rng)]+step)) else: ranges.append('%d-%d:%d' % (data[i], data[i+len(rng)]+step, step)) i += len(rng) return ','.join(ranges) data = [1, 3, 5, 6, 7, 11, 13, 15, 16, 17, 18, 19, 22, 25, 28] print data data_str = list_to_ranges(data) print data_str _list = [] for r in data_str.replace('-',':').split(','): r = [int(a) for a in r.split(':')] if len(r) == 1: _list.extend(r) elif len(r) == 2: _list.extend(range(r[0], r[1])) else: _list.extend(range(r[0], r[1], r[2])) print _list print list(set(_list)) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload