Инкрементно увеличивать ненулевые элементы в списке - PullRequest
0 голосов
/ 04 января 2019

если я получил этот список

a = [1,0,0,1,0,0,0,1]

и я хочу, чтобы он превратился в

a = [1,0,0,2,0,0,0,3]

Ответы [ 6 ]

0 голосов
/ 04 января 2019

Другой вариант: понимание списка из одного списка, без зависимостей.

[ 0 if e == 0 else sum(a[:i+1]) for i, e in enumerate(a) ]

#=> [1, 0, 0, 2, 0, 0, 0, 3]
0 голосов
/ 04 января 2019

Использование числа или общей суммы для замены 1 на сумму 1

In [4]: import numpy as np
In [5]: [i if i == 0 else j for i, j in zip(a, np.cumsum(a))]
Out[5]: [1, 0, 0, 2, 0, 0, 0, 3]
0 голосов
/ 04 января 2019

Настройка для решения № 1 и № 2

from itertools import count

to_add = count()
a = [1,0,0,1,0,0,0,1]

Решение № 1

>>> [x + next(to_add) if x else x for x in a]
[1, 0, 0, 2, 0, 0, 0, 3]

Решение № 2, смешно, но весело

>>> [x and x + next(to_add) for x in a]
[1, 0, 0, 2, 0, 0, 0, 3]

Настройка дляРешение № 3 и № 4

import numpy as np
a = np.array([1,0,0,1,0,0,0,1])

Решение № 3

>>> np.where(a == 0, 0, a.cumsum())
array([1, 0, 0, 2, 0, 0, 0, 3])

Решение № 4 (мой любимый еще)

>>> a*a.cumsum()
array([1, 0, 0, 2, 0, 0, 0, 3])

Все cumsumРешения предполагают, что ненулевые элементы a являются единицами.


Время:

# setup
>>> a = [1, 0, 0, 1, 0, 0, 0, 1]*1000
>>> arr = np.array(a)
>>> to_add1, to_add2 = count(), count()
# IPython timings @ i5-6200U CPU @ 2.30GHz (though only relative times are of interest)
>>> %timeit [x + next(to_add1) if x else x for x in a] # solution 1
669 µs ± 3.59 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit [x and x + next(to_add2) for x in a] # solution 2
673 µs ± 15.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit np.where(arr == 0, 0, arr.cumsum()) # solution 3
34.7 µs ± 94.2 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit arr = np.array(a); np.where(arr == 0, 0, arr.cumsum()) # solution 3 with array creation
474 µs ± 14.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
>>> %timeit arr*arr.cumsum() # solution 4
23.6 µs ± 131 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
>>> %timeit arr = np.array(a); arr*arr.cumsum() # solution 4 with array creation
465 µs ± 6.82 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
0 голосов
/ 04 января 2019

Вот как бы я это сделал:

def increase(l):
    count = 0
    for num in l:
        if num == 1:
            yield num + count
            count += 1
        else:
            yield num

c = list(increase(a))

c

[1, 0, 0, 2, 0, 0, 0, 3]
0 голосов
/ 04 января 2019

Итак, вы хотите увеличить каждое 1, кроме первого, верно?

Как насчет:

a = [1,0,0,1,0,0,0,1]

current_number = 0

for i, num in enumerate(a):
    if num == 1:
        a[i] = current_number + 1
        current_number += 1

print(a)

>>> [1, 0, 0, 2, 0, 0, 0, 3]

Или, если вы предпочитаете:

current_number = 1

for i, num in enumerate(a):
    if num == 1:
        a[i] = current_number
        current_number += 1
0 голосов
/ 04 января 2019

Используйте для этого понимание списка:

print([a[i]+a[:i].count(1) if a[i]==1 else a[i] for i in range(len(a))])

Вывод:

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

Версия цикла:

for i in range(len(a)):
    if a[i]==1:
        a[i]=a[i]+a[:i].count(1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...