找到n个或更少的连续值时替换

时间:2017-12-28 23:02:58

标签: python replace

这可能是一个非常简单的问题

我有一个如下所示的列表:

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

我很难找到一个简单的python代码,当 n 或更少的连续 1s 被发现为0时会替换它并创建一个新的列表使用新值

所以,如果

n = 2

b = [0, 0,0 ,2,3,2, 0 ,2,0,3,4,1,1,1,1, 0,0,0,0,4,5,1,1,1,3,2,0,2,的 0,0 下,3,4,的 0 ]

如果

n = 3

b = [0, 0,0 ,2,3,2, 0 ,2,0,3,4,1,1,1,1, 0,0,0,0,4,5,的 0,0,0 下,3,2,0,2,的 0,0 下,3,4, 0 ]

我在每个示例中都突出显示了新的替换值

5 个答案:

答案 0 :(得分:2)

你可以试试这个:

import itertools
a=[0,1,1,2,3,2,1,2,0,3,4,1,1,1,1,0,0,0,0,4,5,1,1,1,3,2,0,2,1,1,3,4,1]
n = 3
new_list = list(itertools.chain(*[[0]*len(b) if a == 1 and len(b) <= n else b for a, b in [(c, list(d)) for c, d in itertools.groupby(a)]]))

输出:

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

答案 1 :(得分:1)

&#34;一个&#34; -liner,使用一些itertools

from itertools import groupby, chain

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

list(
    chain.from_iterable(
        ([0] * len(lst) if x == 1 and len(lst) <= n else lst 
         for x, lst in ((k, list(g)) for k, g in groupby(a)))
    )
)
# [0,0,0,2,3,2,0,2,0,3,4,1,1,1,1,0,0,0, 0,4,5,1,1,1,3,2,0,2,0,0,3,4,0]

groupby将初始列表分组为相同对象的组。它的输出是成对(k, g)的迭代器,其中k是作为分组键的元素,g是生成组中实际元素的迭代器。

由于您无法在迭代器上调用len,因此除了适当延长的1列表之外,这会对组生成并链接结果列表。这些被替换为相同长度的0列表。

单步执行(使用中间列表而不是生成器):

grouped_lists_by_key = [k, list(g)) for k, g in groupby(a)]
# [(0, [0]), (1, [1, 1]), ...]

grouped_lists = [[0] * len(lst) if x == 1 and len(lst) <= n else lst for x, lst in grouped]
# [[0], [0, 0], [2], [3], ...]

flattened = chain.from_iterable(grouped_lists)
# [0, 0, 0, 2, 3, ...]

答案 2 :(得分:1)

使用itertools.groupby()的非oneliner:

a = [0,1,1,2,3,2,1,2,0,3,4,1,1,1,1,0,0,0,0,4,5,1,1,1,3,2,0,2,1,1,3,4,1]
n = 2
b = []
for k, g in groupby(a):
    l = list(g)
    if k == 1 and len(l) <= n:
        b.extend([0]*len(l))
    else:
        b.extend(l)
print(b)

答案 3 :(得分:0)

试试这个:

def replacer(array, n):
    i, consec = 0, 0
    while i < len(array):
        if array[i] == 1:
            consec += 1
        else:
            if consec >= n:
                for x in range(i-consec, i):
                    array[x] = 0
            consec = 0
        i += 1
    return array

答案 4 :(得分:0)

比其他人更长,但可以说是直截了当的:

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

def suppress_consecutive_generator(consecutive=2, toreplace=1, replacement=0):
    def gen(l):
        length = len(l)
        i = 0
        while i < length:
            if l[i] != toreplace:
                yield l[i]
                i += 1
                continue
            j = i
            count = 0
            while j < length:
                if l[j] != toreplace:
                    break
                count += 1
                j += 1
            i += count
            if count <= consecutive:
                for _ in range(count):
                    yield replacement
            else:
                for _ in range(count):
                    yield toreplace
    return gen

print(list(suppress_consecutive_generator()(a)))