How to do an inverse `range`, i.e. create a compact range based on a set of numbers?

前端 未结 6 653
忘了有多久
忘了有多久 2021-02-06 11:35

Python has a range method, which allows for stuff like:

>>> range(1, 6)
[1, 2, 3, 4, 5]

What I’m looking for is kind of t

6条回答
  •  渐次进展
    2021-02-06 12:02

    Let's try generators!

    # ignore duplicate values
    l = sorted( set( [5,7,9,8,6, 21,20, 3,2,1, 22,23, 50] ) )
    
    # get the value differences 
    d = (i2-i1 for i1,i2 in zip(l,l[1:]))
    
    # get the gap indices
    gaps = (i for i,e in enumerate(d) if e != 1)
    
    # get the range boundaries
    def get_ranges(gaps, l):
      last_idx = -1
      for i in gaps:
        yield (last_idx+1, i)
        last_idx = i
      yield (last_idx+1,len(l)-1)
    
    # make a list of strings in the requested format (thanks Frg!)
    ranges = [ "%s-%s" % (l[i1],l[i2]) if i1!=i2 else str(l[i1]) \
      for i1,i2 in get_ranges(gaps, l) ]
    

    This has become rather scary, I think :)

提交回复
热议问题