Formatting consecutive numbers

后端 未结 5 2049
轻奢々
轻奢々 2021-01-18 15:00

I\'m trying to format a list of integers with Python and I\'m having a few difficulties achieving what I\'d like.

Input is a sorted list of Integers:



        
5条回答
  •  我在风中等你
    2021-01-18 15:55

    You can use groupby and count from itertools module like this way:

    Edit:

    Thanks to @asongtoruin comment. For removing duplicates from the input you can use: sorted(set(a)).

    from itertools import groupby, count
    
    a = [1, 2, 3, 6, 8, 9]
    clustered = [list(v) for _,v in groupby(sorted(a), lambda n, c = count(): n-next(c))]
    
    for k in clustered:
        if len(k) > 1:
            print("{0}-{1}".format(k[0], k[-1]))
        else:
            print("{0}".format(k[0]))
    

    Output:

    1-3
    6
    8-9
    

    Or maybe you can do something like this in order to have a pretty output:

    from itertools import groupby, count
    
    a = [1, 2, 3, 6, 8, 9]
    clustered = [list(v) for _,v in groupby(sorted(a), lambda n, c = count(): n-next(c))]
    out = ", ".join(["{0}-{1}".format(k[0], k[-1]) if len(k) > 1 else "{0}".format(k[0]) for k in clustered ])
    
    print(out)
    

    Output:

    1-3, 6, 8-9
    

    Update:

    I'm guessing, using itertools modules may confuse many Python's new developers. This is why i decided to rewrite the same solution without importing any package and trying to show what groupby and count are doing behind the scenes:

    def count(n=0, step=1):
        """Return an infinite generator of numbers"""
        while True:
            n += step
            yield n
    
    
    def concat(lst):
        """Group lst elements based on the result of elm - next(_count)"""
        _count, out = count(), {}
        for elm in sorted(lst):
            c = elm - next(_count)
            if c in out:
                out[c].append(elm)
            else:
                out[c] = [elm]
        return out
    
    
    def pretty_format(dct):
        for _, value in dct.items():
            if len(value) > 1:
                yield '{}-{}'.format(value[0], value[-1])
            else:
                yield '{}'.format(value[0])
    
    
    lst = [1, 2, 3, 6, 8, 9]
    dct = concat(lst)
    formatted = list(pretty_format(dct))
    print(formatted)
    

    Output:

    ['1-3', '6', '8-9']
    

提交回复
热议问题