从python列表里删除一个元素会对reversed() 产生怎样的影响

这是一个在stackoverflow上看到的问题,非常的有趣且值得研究。

1. iter

使用iter函数返回列表的迭代器,随后从列表里删除一个元素,在遍历迭代器时,输出的内容会是怎样的呢?

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

考虑2分钟,想一想print函数会输出什么呢?答案是

['a', 'b', 'd']

从列表里删除元素c并不影响迭代器的使用,这也揭示了迭代器的本质,迭代器本身并不保存数据而是对数据进行迭代遍历,在迭代遍历时列表lst中已经没有了c,自然也就不会输出c。

2. reversed

reversed 返回一个反向迭代器,接下来对列表做同样的事情

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

猜猜这次会输出什么内容呢?答案很意外,不是['a', 'b', 'd'], 而是[],最终输出的是空列表。

这是为什么呢?然我们回到迭代器的本质上来寻找答案。迭代器本身并不存储数据,这一点很关键,它自身存储一个迭代开始的位置,每次对它调用next函数时都会遍历到可迭代对象的下一个元素。rev_iter_lst 所记录的迭代开始的位置是d的索引位置3,由于删除了c,导致d向前移动了一位,d的索引位置变成了2,原来的索引3位置上没有任何数据了,这导致rev_iter_lst在遍历时得到一个空的列表。

如果前面的理解都正确,在删除c后,再向列表里增加一个新的元素,索引3的位置上就会补充一个新的元素,这样rev_iter_lst 仍然可以正常工作,实验一下

lst = ['a', 'b', 'c', 'd']
rev_iter_lst = reversed(lst)
lst.remove('c')
lst.append('ok')
print(list(rev_iter_lst))

输出内容为

['ok', 'd', 'b', 'a']

果真如此。

扫描关注, 与我技术互动

QQ交流群: 211426309

加入知识星球, 每天收获更多精彩内容

分享日常研究的python技术和遇到的问题及解决方案