我有一个零和一个列表,如下所示:
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]
答案 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]