简体   繁体   English

将整数列表转换为连续正整数列表

[英]Convert a list of integers to a list of consecutive positive integers

I came up with this code to convert a list of already ordered integers into a list of consecutive positive integers.我想出了这段代码,将已经排序的整数列表转换为连续正整数的列表。

def consecutive_positive_inc(l):
    """
    [0, 1, 1, 3, 4, 4, 5] -> [0, 1, 1, 2, 3, 3, 4]
    """
    from collections import defaultdict

    d = defaultdict(int)
    for i in l:
        d[i] += 1

    for i, count in enumerate(d.values()):
        for _ in range(count):
            yield i


if __name__ == '__main__':
    l = [-3, -2, -1, 0, 1, 1, 3, 4, 4, 5]
    result = list(consecutive_positive_inc(l))
    assert result == [0, 1, 2, 3, 4, 4, 5, 6, 6, 7]

Is it the best way to do it or something much simpler could be used?这是最好的方法还是可以使用更简单的方法?

I think you've made it more complicated than it needs to be.我认为你让它变得比它需要的更复杂。 Just keep a counter and bump when the number changes.只需保留一个计数器并在数字更改时碰撞。

def consecutive_positive_inc(l):
    """
    [0, 1, 1, 3, 4, 4, 5] -> [0, 1, 1, 2, 3, 3, 4]
    """
    last = l[0]
    idx = 0
    for i in l:
        if i != last:
            idx += 1
            last = i
        yield idx


if __name__ == '__main__':
    l = [-3, -2, -1, 0, 1, 1, 3, 4, 4, 5]
    result = list(consecutive_positive_inc(l))
    assert result == [0, 1, 2, 3, 4, 4, 5, 6, 6, 7]

itertools.groupby : itertools.groupby

from itertools import groupby

def consecutive_inc(iterable, start=0):
    """
    >>> list(consecutive_inc([0, 1, 1, 3, 4, 4, 5]))
    [0, 1, 1, 2, 3, 3, 4]
    """
    return (i for i, (_, g) in enumerate(groupby(iterable), start) for _ in g)

This uses O(1) space and works on arbitrary iterables.这使用 O(1) 空间并适用于任意迭代。

You can use a dict like a mathematical set to keep track of how many unique numbers you have seen before:您可以使用像数学集这样的dict来跟踪您之前看到的唯一数字的数量:

def consecutive_positive_inc(l):
  m = {}
  r = []
  for i in l:
    m[i] = None
    r.append(len(m) - 1)
  return r

You can do this in one line with a collections.Counter :您可以使用collections.Counter在一行中执行此操作:

>>> from collections import Counter
>>> def consecutive_positive_inc(arr):
...     return [i for i, count in enumerate(Counter(arr).values()) for _ in range(count)]
...
>>> consecutive_positive_inc([0, 1, 1, 3, 4, 4, 5])
[0, 1, 1, 2, 3, 3, 4]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM