squa sh все последовательные в списке python - PullRequest
2 голосов
/ 17 июня 2020

У меня есть списки переменных, заполненные 0s и 1s, например:

l1 = [1,1,1,0,1,1]
l2 = [0,1,1,0,1,1,0,0,1]

, что является наиболее эффективным способом создания новых списков, которые включают sh все подряд 1s.

Таким образом, результат будет:

l1_new = [1,0,1]
l2_new = [0,1,0,1,0,0,1]

Подсказка: numpy / векторизация или какая-то логическая операция были бы отличными!

Ответы [ 5 ]

3 голосов
/ 18 июня 2020

Вот один из подходов с использованием np.diff и bitwise operations:

l1 = [1,1,1,0,1,1]
l2 = [0,1,1,0,1,1,0,0,1]

a = np.array(l2)
a[~((np.diff(a,prepend=False)==0) & (a==1))]
# array([0, 1, 0, 1, 0, 0, 1])

Или для первого примера:

a = np.array(l1)
a[~((np.diff(a,prepend=False)==0) & (a==1))]
#array([1, 0, 1])
3 голосов
/ 17 июня 2020

Чтобы использовать NumPy, нам понадобится массив, поэтому после этого преобразования мы создадим соответствующую маску и индекс -

def squash1s(a):
    a = np.asarray(a)
    m = a==1
    return a[np.r_[True,m[:-1]!=m[1:]] | (a==0)]

Примеры прогонов -

In [64]: l1 = [1,1,1,0,1,1]
    ...: l2 = [0,1,1,0,1,1,0,0,1]

In [65]: squash1s(l1)
Out[65]: array([1, 0, 1])

In [66]: squash1s(l2)
Out[66]: array([0, 1, 0, 1, 0, 0, 1])

Тестирование

Поскольку нас интересует эффективность производительности, давайте проверим тесты NumPy, так как они должны быть довольно эффективными.

Другие предлагаемые решения

# @yatu's solution
def yatu_diff(l):
    a = np.asarray(l)
    return a[~((np.diff(a,prepend=False)==0) & a==1)]

# PaulPanzer's suggestion/soln
def pp_concat(a):
    a = np.asarray(a)
    return a.repeat(1-(a*np.concatenate([[0],a[:-1]])))

Использование пакета benchit (несколько инструментов тестирования собраны вместе; отказ от ответственности: я являюсь его автором) для тестирования предлагаемых решений.

import benchit

funcs = [squash1s, yatu_diff, pp_concat]

# With ~30% 0s
in_ = [(np.random.rand(n)>0.3).astype(int) for n in 10**np.arange(4)]
t = benchit.timings(funcs, in_)
t.plot(logx=True, save='timings30.png')

# With ~70% 0s
in_ = [(np.random.rand(n)>0.7).astype(int) for n in 10**np.arange(4)]
t = benchit.timings(funcs, in_)
t.plot(logx=True, save='timings70.png')

С ~30% 0s:

enter image description here

С ~70% 0 с:

enter image description here

0 голосов
/ 18 июня 2020

Дано

lst_1 = [1, 1, 1, 0, 1, 1]
lst_2 = [0, 1, 1, 0, 1, 1, 0, 0, 1]
lst_3 = [0, 1, 1, 0, 1, 1, 0, 0, 1, 1]

Код

def compress_values(seq, value=1):
    """Yield a value in isolation."""

    for here, nxt in zip(seq, seq[1:]):

        if here == nxt == value:
            continue
        else:
            yield here

    yield nxt        

Демо

assert [1, 0, 1] == list(compress_values(lst_1))
assert [0, 1, 0, 1, 0, 0, 1] == list(compress_values(lst_2))
assert [0, 1, 0, 1, 0, 0, 1] == list(compress_ones(lst_3))

Подробности

Сдвинуть окно с двумя кортежами. Если значения равны друг другу и целевому value, пропустите. В противном случае выведите значения.

Альтернативный, более общий подход:


import itertools as it


def squash(seq, values=(1,)):
    """Yield singular values in isolation."""

    for k, g in it.groupby(seq):

        if k in values:
            yield k
        else:
            yield from g

0 голосов
/ 17 июня 2020

Используя время l oop,

l1 = [1,1,1,0,1,1]
i = 0

while i < len(l1)-1:
    if l1[i] == l1[i+1]:
        del l1[i]
    else:
        i = i+1
print(l1)

еще один, который я нашел на geekforgeeks,

from itertools import zip_longest 


test_list = [1, 4, 4, 4, 5, 6, 7, 4, 3, 3, 9] 

res = [i for i, j in zip_longest(test_list, test_list[1:]) 
                                                if i != j] 
0 голосов
/ 17 июня 2020

Вот возможное решение

arr = [0,1,1,0,1,1,0,0,1]

previous_value = None
new_lst = []

for elem in arr:
   if elem != previous_value:
       new_lst.append(elem)
       previous_value = elem

print(new_lst)

Где arr - это любой список, который вы хотите, и он будет работать со всем, включая строки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...