基于数字模式的增量列表

时间:2012-11-27 18:26:21

标签: python list

我有一个零和一个列表,如下所示:

lst = [0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1]

我如何将此信息转换为:

transformed_lst = lst = [0, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 3, 0, 4, 4]

基本上,在每次出现1时,将其转换为n + 1整数。我确信使用itertools / groupby / functools有一种优雅的方法。这是一次尝试,但不太正确:

from itertools import cycle

ints = cycle(range(len(lst))) 
transformed_lst = [next(ints) if i != 0 in lst else 0 for i in lst]  

>>> [0, 0, 1, 2, 3, 0, 0, 0, 4, 5, 0, 0, 0, 6, 0, 7, 8]  

6 个答案:

答案 0 :(得分:6)

你基本上有两种状态 - “阅读0 s”和“阅读1 s” - 当你在当时(即从1到0)之间切换时,要应用于后续的增量{ {1}}改变:

1

答案 1 :(得分:3)

使用itertools.count()itertools.chain()itertools.groupby()

In [14]: from itertools import *

In [15]: c=count(1)

In [16]: lis=[0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1]

In [17]: list(chain(*[list(g) if k!=1 else [next(c)]*len(list(g)) for k,g in groupby(lis)]))

Out[17]: [0, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 3, 0, 4, 4]

您也可以使用sum(1 for _ in g)代替len(list(g))

根据要求,使用生成器功能的可读版本:

In [27]: def func(l):
    c=count(1)
    for k,g in groupby(l):
        if k==1:
            for x in [next(c)]*sum(1 for _ in g):
                yield x
        else:
            for x in g:
                yield x
   ....:                 

In [28]: list(func(lis))
Out[28]: [0, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 3, 0, 4, 4]

答案 2 :(得分:3)

请注意,当前元素为1且前一个元素为0时,您只有一个“下一个组”。

previous = 0
grp = 0
for elem in lst:
    if elem and not previous:
         grp += 1
    previous = elem
    yield (grp if elem else 0)

答案 3 :(得分:2)

>>> lst = [0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1]
>>> from itertools import groupby
>>> [i//2 if k else 0 for i, (k, g) in enumerate(groupby(lst), 2) for j in g]
[0, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 3, 0, 4, 4]

答案 4 :(得分:0)

>>> lst = [0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1]
>>> transformed = []
>>> idx = 1
>>> for key, grp in groupby(lst):
...    if key:
...       transformed += [idx] * len(list(grp))
...       idx += 1
...    else:
...       transformed += list(grp)
... 
>>> transformed
[0, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 3, 0, 4, 4]
>>> 

答案 5 :(得分:0)

我发现这是可读性和简洁性之间的良好结合(不需要跟踪状态):

from itertools import groupby

def transform(numbers):
    counter = 0
    for value, iterator in groupby(numbers):
        if value:
            counter += 1

        for i in iterator:
            if value:
                yield counter
            else:
                yield 0

pre_transformed = [0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 1, 1]
print list(transform(pre_transformed))

返回:

[0, 1, 1, 1, 1, 0, 0, 0, 2, 2, 0, 0, 0, 3, 0, 4, 4]