使用产量生成器从列表中删除连续的重复项?

bie*_*ogy 4 python iterator python-3.x yield-from

我正在尝试使用生成器压缩列表:

例子

[1, 1, 1, 1, 2, 2, 2, 1, 1, 1] == [1, 2, 1]

[5, 5, 5, 4, 5, 6, 6, 5, 5, 7, 8, 0, 0])) == [5, 4, 5, 6, 5, 7, 8, 0]
Run Code Online (Sandbox Code Playgroud)

我尝试使用一个生成器来检查第 1 个和第 2 个元素是否相等,然后检查第 2 个和第 3 个元素,依此类推,直到它不再相等“当它达到 4”然后产生“5”然后它会重复从“4”

代码

test = [5, 5, 5, 4, 5, 6, 6, 5, 5, 7, 8, 0, 0] # sample list
from typing import Iterable
def compress(items: list) -> Iterable:

    x = 0
    while items[x] == items[x + 1]:
        x += 1
    yield items[x]


ans = compress(test)
for x in ans:
    print(ans)
Run Code Online (Sandbox Code Playgroud)

但我不断得到

生成器对象压缩在 0x00000254D383C820。为什么它不会循环?

如果我尝试使用 next() 它只会增加到 5 并且不会检查其他数字。

非常感谢任何帮助。

cs9*_*s95 12

正如其他人所解释的那样,您的结构不正确 - 您只会在循环外遇到一次产量。理想的方法是迭代成对的连续数字,如果它们不同,则产生循环中的第一个。

但是,这里有一个规范的方法,通过itertools.groupby它删除连续的重复项:

from itertools import groupby 
from operator import itemgetter

list(map(itemgetter(0), groupby(l)))
# [1, 2, 1]
Run Code Online (Sandbox Code Playgroud)


Dr.*_*. V 4

所以存在几个缺陷,所有这些缺陷都被描述为对问题帖子的评论。

  • 缺少一个循环,该循环会产生多个值
  • 您打印ans而不是x,这在逻辑上是生成器对象。

这段代码对你有用吗?

test = [5, 5, 5, 4, 5, 6, 6, 5, 5, 7, 8, 0, 0]

def compress(items):
    for i, d in enumerate(items[:-1]):
        if d == items[i+1]:
            continue
        yield d
    yield items[-1]

for x in compress(test):
    print(x)
Run Code Online (Sandbox Code Playgroud)