Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 是否使用产量生成器从列表中删除连续重复项?_Python_Python 3.x_Iterator_Yield From - Fatal编程技术网

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

Python 是否使用产量生成器从列表中删除连续重复项?,python,python-3.x,iterator,yield-from,Python,Python 3.x,Iterator,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] 我尝试使用一个生成器,检查第一个和第二个元素是否相等,然后检查第二个和第三个元素,依此类推,直到“当它达到4”时不再相等,然后产生“5”,然后它将重复从“4”开始的过程 代码 但我一直在 生成器对象在0x00000254D383C

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

例子

[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]
我尝试使用一个生成器,检查第一个和第二个元素是否相等,然后检查第二个和第三个元素,依此类推,直到“当它达到4”时不再相等,然后产生“5”,然后它将重复从“4”开始的过程

代码 但我一直在

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

如果我尝试使用next(),它只升到5,不会检查其他数字


非常感谢您的帮助。

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

但是,这里有一个标准方法,通过它可以删除连续的重复项:

from itertools import groupby 
from operator import itemgetter

list(map(itemgetter(0), groupby(l)))
# [1, 2, 1]

如果您正在寻找与此相同的效果,请查看
itertools.groupby
函数。使用内置工具更明智

如果你对学习生成器感兴趣,就写下来。除了在错误的级别上使用“yield”之外,您没有犯任何错误,但是您编写了非Python代码。跟踪x和x+1,并将整个事情都保存在内存中都是不好的

class NeverInList: pass


from typing import Iterable
def compress(items: list) -> Iterable:
    previous = NeverInList()  # Something never in a list, duh. 
    for item in items:
        if item != previous:
            yield item
            previous = item


ans = compress(test)
for x in ans:
    print(x)   # "x", not "ans"

因此有几个缺陷,都被描述为对问题帖子的评论

  • 缺少一个将产生多个值的循环

  • 打印的是
    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)

您需要实现
堆栈
,并查看列表的最后一个元素是否与value相同

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

def funct(lis):
    l = []
    for val in lis:
        if len(l) ==0:
            l.append(val)
            yield val
        if l[-1] != val:
            l.append(val)
            yield val


for result in funct(test):
    print(result)
输出

5
4
5
6
5
7
8
0
方法二,在O(N)时间复杂度和O(1)空间复杂度中使用
比较变量

def funct(lis):
    checker = None
    for val in lis:
        if checker != val:
            checker = val 
            yield val

嘿,我从某处认出了这个问题

我用了一种不同于你的方式,但我想你可能会发现偷看一下很有用:

def compress(i:list):
    return[i[x]for x in range(len(i))if x==0 or i[x-1]!=i[x]]

其他答案更符合您问题的具体情况,我只是碰巧认识到了设置,并认为我会深入研究并提供解决方案,我给了这个非常相同的问题。干杯

还有一个解决方案:检查列表和同一列表的组合,将其移位一(换言之,由连续项目对移位),并从第一个(上一个)项目与第二个(下一个)项目不同的每对中选择第二个项目:


顺便说一句,这是迄今为止提出的最快的解决方案之一。

您的生成器只遇到一次
yield
语句。这就是为什么它只能产生一个值。一旦到达函数的结尾,函数退出,生成器结束。没有隐式循环行为。打印的是
ans
,而不是
x
。。。加上timgeb的注释-必须在循环中测试x以达到
len(items)
请参见。作为
NeverInList
的替换,
previous=object()
应该足够了。我以前使用过哨兵值的
object
,效果很好。这个问题有O(1)个解决方案,但这不是其中之一。
def compress(i:list):
    return[i[x]for x in range(len(i))if x==0 or i[x-1]!=i[x]]
l = [5, 5, 5, 4, 5, 6, 6, 5, 5, 7, 8, 0, 0]
[l[0]] + [y for x,y in zip(l, l[1:]) if x!=y]
#[5, 4, 5, 6, 5, 7, 8, 0]