2

次のようなゼロと 1 のリストがあります。

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

この lst を次のように変換するにはどうすればよいですか。

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]  
4

6 に答える 6

6

基本的に、「reading 0s」と「reading 1s」の 2 つの状態があり、その間を (つまり、1 から 0 に) 切り替えると、後続1の s に適用されるデルタが変更されます。

reading_zeroes = True
delta = 0
for x in input:
    if x:
        reading_zeroes = False
        x += delta
    elif not reading_zeroes:
        delta += 1
        reading_zeroes = True
    yield x
于 2012-11-27T18:39:56.167 に答える
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)
于 2012-11-27T19:00:50.703 に答える
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]
于 2012-11-27T18:33:37.903 に答える
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]
于 2012-11-27T18:52:43.803 に答える
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]
于 2012-11-27T18:52:00.293 に答える
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]
>>> 
于 2012-11-27T18:40:31.533 に答える