Identify groups of varying continuous numbers in a list

前端 未结 4 835
囚心锁ツ
囚心锁ツ 2020-12-17 20:56

In this other SO post, a Python user asked how to group continuous numbers such that any sequences could just be represented by its start/end and any stragglers would be dis

4条回答
  •  失恋的感觉
    2020-12-17 21:43

    Here is a quickly written (and extremely ugly) answer:

    def test(inArr):
        arr=inArr[:] #copy, unnecessary if we use index in a smart way
        result = []
        while len(arr)>1: #as long as there can be an arithmetic progression
            x=[arr[0],arr[1]] #take first two
            arr=arr[2:] #remove from array
            step=x[1]-x[0]
            while len(arr)>0 and x[1]+step==arr[0]: #check if the next value in array is part of progression too
                x[1]+=step #add it
                arr=arr[1:]
            result.append((x[0],x[1],step)) #append progression to result
        if len(arr)==1:
            result.append(arr[0])
        return result
    
    print test([2, 4, 6, 8, 12, 13, 14, 15, 16, 17, 20])
    

    This returns [(2, 8, 2), (12, 17, 1), 20]

    Slow, as it copies a list and removes elements from it

    It only finds complete progressions, and only in sorted arrays.

    In short, it is shitty, but should work ;)

    There are other (cooler, more pythonic) ways to do this, for example you could convert your list to a set, keep removing two elements, calculate their arithmetic progression and intersect with the set.

    You could also reuse the answer you provided to check for certain step sizes. e.g.:

    ranges = []
    step_size=2
    for key, group in groupby(enumerate(data), lambda (index, item): step_size*index - item):
        group = map(itemgetter(1), group)
        if len(group) > 1:
            ranges.append(xrange(group[0], group[-1]))
        else:
            ranges.append(group[0])
    

    Which finds every group with step size of 2, but only those.

提交回复
热议问题