什么是Pythonic方法来删除列表中的双重副本但允许三元组/更大?

Sha*_*ang 5 python list

我有一个Python列表

list1 = [0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

有连续1和0的"分组".为了我的目的,我只对连续1的感兴趣.让我们说如果有一个孤独的1,例如

 ... 0, 0, 1, 0, 0 ...
Run Code Online (Sandbox Code Playgroud)

我希望它变成0.同样,如果只有1对,那么这些也应该变为0.例如

.... 0, 0, 1, 1, 0, 0...
Run Code Online (Sandbox Code Playgroud)

应该成为

.... 0, 0, 0, 0, 0, 0...
Run Code Online (Sandbox Code Playgroud)

但连续的或更高的"三胞胎"是可以的.

我考虑通过字典跟踪1的计数,但这感觉太复杂了.我们的想法是遍历列表,跟踪列表中连续1的计数.但是,你如何"回去"并将1s切换为0?

counter_list = []
for i in list1: 
    if i == 1:
        counter_list = counter_list + 1
            if len(counter_list)==1 or len(counter_list)==2:
                # now I don't know how to "go back" to change these elements into 0s
Run Code Online (Sandbox Code Playgroud)

wim*_*wim 7

这是一种侵蚀,随后是扩张,计算机视觉中的常见操作:

>>> from scipy.ndimage.morphology import binary_dilation, binary_erosion
>>> print(list1)
[0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1]
>>> print(binary_dilation(binary_erosion(list1)).astype(int))
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

这两个操作的组成称为开放:

>>> from scipy.ndimage.morphology import binary_opening
>>> print(binary_opening(list1).astype(int))
[0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

  • 我的回答是一分钟太晚了=).这种构成称为开放. (2认同)

yar*_*yar 6

您可以使用图像处理方法.结构元素[111]的形态操作"打开"应该起作用.应该是一个班轮.


use*_*ica 4

itertools.groupby可以通过将列表分组为 0 或 1 来提供帮助。从那里,我们可以使用一组 1 的长度来决定是否将其切换为 0,并使用itertools.chain.from_iterable将这些组融合回一个流:

import itertools

groups = ((key, list(group)) for key, group in itertools.groupby(list1))

fixed_groups = (group if key==0 or len(group)>2 else [0]*len(group)
                for key, group in groups)

result = list(itertools.chain.from_iterable(fixed_groups))
Run Code Online (Sandbox Code Playgroud)

  • @ShanZhengYang:实际上,我希望“binary_opening”的效率更高,特别是如果您使用 NumPy 数组而不是列表。 (2认同)