dwa*_*son 3 python reverse iterator generator python-3.x
为什么删除项目列表中断reversed 对象?它不会破坏gen-exprs,并且追加或修改列表不会破坏reversed对象,它显然指向原始对象,为什么它不能给出截断版本?也许一些例子可以澄清:
l = [1, 2, 3, 4]
r = reversed(l)
g = (i for i in l)
l.pop() # returns 4
l # returns [1, 2, 3]
for i in g:print(i) # prints 1 2 3 (on separate lines)
for i in r:print(i) # prints ...nothing
r = reverse(l)
g = (i for i in l)
l[1] = 4
for i in g:print(i) # prints 1 4 3 (on separate lines)
for i in r:print(i) # prints 3 4 1 (on separate lines)
r = reversed(l)
g = (i for i in l)
l.append(5)
l # returns [1, 4, 3, 5] just to keep you on your toes
for i in g:print(i) # prints 1 4 3 5 (on separate lines)
for i in r:print(i) # prints 3 4 1 (on separate lines)
Run Code Online (Sandbox Code Playgroud)
那么 - 如果genexpr足够智能指向对象,只是响应对象已经改变,为什么不reversed呢?它显然不会复制,否则它不会在第一种情况下"失败",并且它不会4在第二种情况下获得.所以它必须指向对象.为什么它不能从索引开始-1并向后工作?
当您调用reversed()列表对象时,会创建一个专用的反向列表迭代器对象; 这个对象'知道'如何以相反的顺序有效地迭代列表一次.
为此,在创建对象时,将存储列表中的最后一个索引.对于你的列表l,即3(第4个元素,从0开始计算).然后,当您进行迭代时,将生成该索引处的元素,并且索引将递减,直到a IndexError被引发*.
该对象的Python实现如下所示:
class reversed_list_iterator(object):
def __init__(self, lst):
self.index = len(lst) - 1
self.lst = lst
def __iter__(self):
return self
def __next__(self):
try:
result = self.lst[self.index]
except IndexError:
self.lst = [] # switch to permanently stopped state
raise StopIteration
self.index -= 1
return result
Run Code Online (Sandbox Code Playgroud)
现在,当你删除那个元素时,迭代器会退出,因为没有l[3],IndexError会在那里引发,然后迭代结束.
在第二个示例中,在创建反转迭代器时,最后一个索引是2.然后,您将添加到列表中,但迭代开始于l[2],仍然存在.
反向列表迭代器不能使用相对索引,因为正如您所发现的那样,迭代器相对容忍要添加到列表中的元素.然后,相对索引将重复值.
*在实际的C实现测试的边界0 <= index < len(self.lst),而不是追赶IndexError,但原理是一样的.
| 归档时间: |
|
| 查看次数: |
1922 次 |
| 最近记录: |