今天看见个问题:
一个在坐牢的犯人想要出去,钥匙在警卫那里,警卫有十个,现在十个警卫依次排开报数,每报数报道5的时候就杀死一个警卫,然后接着后边的人从1开始报数,一直这样到最后一个警卫。用python写出来。
突然想写一个可以一直循环的迭代器:
class Mylist(object):
def __init__(self):
self.items = []
def add_items(self, num):
self.items.append(num)
def look_all(self):
return self.items
def __iter__(self):
myiterator = MyIterator(self)
return myiterator
class MyIterator(object):
def __init__(self, mylist):
self.mylist = mylist
self.current = 0
def __iter__(self):
return self
def __next__(self):
if self.current >= len(self.mylist.items) > 1:
self.current = 0
if self.current < len(self.mylist.items) > 1:
items = self.mylist.items[self.current]
self.current += 1
return items
if len(self.mylist.items) == 1: # 终止条件
raise StopIteration
if __name__ == '__main__':
mylist = Mylist()
for i in range(1, 11):
mylist.add_items('狱警%s' % i)
print(mylist.look_all())
import time
for i in mylist:
time.sleep(1)
print(i)
结果 是可以一直循环的,但是这样有点麻烦,直接写迭代器不就行啦,代码如下:
import time
class MyIterator(object):
def __init__(self):
self.police = ['狱警1', '狱警2', '狱警3', '狱警4', '狱警5', '狱警6', '狱警7', '狱警8', '狱警9', '狱警10']
self.current = 0
def __next__(self):
if self.current == len(self.police)>1:
self.current = 0
if self.current < len(self.police)>1:
police = self.police[self.current]
self.current += 1
return police
else:
raise StopIteration
def __iter__(self):
return self
if __name__ == '__main__':
kill_five = MyIterator()
for i in kill_five:
print(i)
time.sleep(1)
结果也是可以一直循环的,但是有一个问题,列表在删除元素的时候会影响下一个索引,比如:[1,2,3,4,5] 在索引到2时,把2删除掉,继续for索引的值就变成4啦,不是3,那能不能写一个删除不会影响索引的迭代器呢?
代码如下:
import time
# 本次删除不会影响继续的随影工作的迭代器
class Kill_five(object):
def __init__(self):
self.police = ['狱警1', '狱警2', '狱警3', '狱警4', '狱警5', '狱警6', '狱警7', '狱警8', '狱警9', '狱警10']
self.current = 0
# 根据成员删除
def kill(self, items):
if not (items == self.police[(len(self.police)-1)]): # 判断删除是不是最后一个,删除后,索引减一
self.police.remove(items)
self.current -= 1
else: # 最后一个成员不影响
self.police.remove(items)
def __next__(self):
if self.current >= len(self.police) > 1:
self.current = 0
if self.current < len(self.police) > 1:
police = self.police[self.current]
self.current += 1
return police
if len(self.police) == 1:
raise StopIteration
def __iter__(self):
return self
if __name__ == '__main__':
kill_five = Kill_five()
n = 0
for i in kill_five:
time.sleep(1)
n += 1
if n == 5:
kill_five.kill(i)
print('kill', i)
n = 0
在循环索引的过程里,如果删除的是最后一个元素,就正常删除,如果不是最后一个元素,下一次索引应该减1。
最后把这个可以一直循环索引,删除不会影响下一个索引的迭代器整理了一下:
import time
class Mylist(object):
def __init__(self):
self.items = []
self.current = 0
# 增加元素
def add_item(self, item):
self.items.append(item)
# 查看mylist
def __str__(self):
return str(self.items)
# 根据元素删除
def del_item(self, items):
if not (items == self.items[(len(self.items)-1)]):
self.items.remove(items)
self.current -= 1
else:
self.items.remove(items)
def __next__(self):
if self.current >= len(self.items) > 1:
self.current = 0
if self.current < len(self.items) > 1:
police = self.items[self.current]
self.current += 1
return police
if len(self.items) == 1:
raise StopIteration
def __iter__(self):
return self
if __name__ == '__main__':
police = Mylist()
for i in range(1, 11):
police.add_item('狱警%d' % i)
print(police)
n = 0
for i in police:
time.sleep(1)
n += 1
if n == 5:
police.del_item(i)
print('kill', i)
n = 0