程序问答   发布时间:2022-06-02  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了删除列表项对 python 中 reversed() 的影响大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

如何解决删除列表项对 python 中 reversed() 的影响?

开发过程中遇到删除列表项对 python 中 reversed() 的影响的问题如何解决?下面主要结合日常开发的经验,给出你关于删除列表项对 python 中 reversed() 的影响的解决方法建议,希望对你解决删除列表项对 python 中 reversed() 的影响有所启发或帮助;

据我所知,reversed() 函数提供了一个迭代器,其工作方式与 iter() 类似,但会以相反的顺序提供项目。但是,我遇到了从 reversed() 函数返回的对象的奇怪行为。

通过查看:

lst = ['a','b','c','d']
iter_lst = iter(lst)
lst.remove('c')
print(List(iter_lst))

输出:['a','d']

正如预期的那样。但是:

lst = ['a','d']
rev_iter_lst = reversed(lst)
lst.remove('c')
print(List(rev_iter_lst))

输出:[]

不应该是:['d','a'] 吗?

列表对象中的 __reversed__() 方法或迭代器对象中的 __next__() 方法的实现是否阻止了这种情况?我的意思是如果原始列表中的某些内容发生变化,它可能不会产生反向序列...

更新:我已经发布了一个可能的解决方法here,我已经对其进行了测试,但我不知道这种实现是否会出现这种情况给出无例外的结果。

解决方法

根据list.__reversed__ source code,迭代器记住最后一个索引地址,并返回记住最后一个索引地址的迭代器。 现在,当您删除一个项目时,它将移动所有索引并使最后一个地址指向任何地方,它将返回一个空列表,因为没有任何内容可以迭代。 让我描述更多: 虑以下列表:lst = ['a','b','c'] 还假设 lst[0] 在 100 处,每个字符是一个字节,因此字符 'c' 在 102 中。 当您创建一个受人尊敬的迭代器时,它会记住 102 作为起点。 在下一步中,我们省略 'b' 现在字符 'c' 在地址 101 中。 当你要求迭代器迭代时,它会开始查看位置 102。它会在那里找到什么?字面上什么都没有,显然它会返回一个空列表。

我希望这会有所帮助:)

编辑:字地址不正确。我必须改用索引...

,

所以在与@kkasra12 讨论之后,我最终实现了 Python 的伪列表对象(没有做所有必要的检查)来模仿它的行为,我只关注 reverse() 操作。这是我的课:

class MyList:
    def __init__(self,n):
        self.length = n
        self._seq = list(range(n))

    @property
    def seq(self):
        return self._seq

    def __len__(self):
        return self.length

    def __getitem__(self,item):
        return self._seq[item]

    def __setitem__(self,idx,value):
        self._seq[idx] = value

    def __reversed__(self):
        return ReverseIterator(self)

    def __str__(self):
        return str(self._seq)

    def append(self,v):
        self._seq.append(v)
        self.length += 1

    def remove(self,v):
        self._seq.remove(v)
        self.length -= 1

还有我的ReverseIterator

class ReverseIterator:
    def __init__(self,org):
        self.org = org
        self._index = org.length

    def __iter__(self):
        return self

    def __next__(self):
        if 0 < self._index:
            try:
                item = self.org.seq[self._index - 1]
                self._index -= 1
                return item
            except IndexError:
                raise StopIteration()
        else:
            raise StopIteration()

结果:

obj = MyList(6)
iter_obj = iter(obj)
obj.remove(2)
print(list(iter_obj))

print('-----------------------')

obj = MyList(6)
rev_iter_obj = reversed(obj)
obj.remove(2)
print(list(rev_iter_obj))

输出:

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

通过注释上面的那些 remove 语句,我们可以看到它的工作方式类似于原始 list 对象。

然后我创建了新的 smartReverseIterator 迭代器,它可以处理是否从原始对象中删除了一个项目,并且可以动态生成值,就像 iter() 在 OP 中的列表中一样。>

唯一应该虑的是,如果删除了一个项目(self._index 将小于原始对象的长度),则应该重置 self._index

class smartReverseIterator:
    def __init__(self,org):
        self.org = org
        self._index = org.length

    def __iter__(self):
        return self

    def __next__(self):
        if 0 < self._index:
            try:
                item = self.org.seq[self._index - 1]
                return item

            except IndexError:
                self._index = self.org.length
                item = self.org.seq[self._index - 1]
                return item

            finally:
                self._index -= 1
        else:
            raise StopIteration()

通过改变 __reversed__ 上的 @H_184_3@myList 方法来返回这个新的迭代器,结果将是:

obj = MyList(6)
iter_obj = iter(obj)
obj.remove(2)
print(list(iter_obj))

print('-----------------------')

obj = MyList(6)
rev_iter_obj = reversed(obj)
obj.remove(2)
print(list(rev_iter_obj))

输出:

[0,5]
-----------------------
[5,0]

我想知道这是否有任何缺点,或者换句话说,为什么 python 决定不在 __reversed__ 这样的对象上实现 list 方法,以得出 iter() 如何生成值如果删除了一个项目。

在什么情况下我们会看到问题?

,

list 调用将迭代反向迭代器,其 index < PyList_GET_SIZE(seq) 检查 here 将失败,因为您在此期间缩小了 seq,因此不会产生值但停止:

listreviter_next(listreviterobject *it)
{
    (some checks)
    index = it->it_index;
    if (index>=0 && index < PyList_GET_SIZE(seq)) {
        (decrease the index and return the element)
    }
    (stop the iteration)
}

大佬总结

以上是大佬教程为你收集整理的删除列表项对 python 中 reversed() 的影响全部内容,希望文章能够帮你解决删除列表项对 python 中 reversed() 的影响所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。