У меня есть ситуация, когда цикл for вне класса взаимодействует с перечислением внутри класса.Python enumerate in for loop пропускает альтернативные элементы
Пример кода:
class MyContainerClass(object):
def __init__(self):
self.collection = []
def __str__(self):
return (len(self.collection) == 0 and 'Empty' or
', '.join(str(item) for item in self.collection))
def __iadd__(self,item):
print "adding {item}".format(item=str(item))
self.collection.append(item)
return self
def __iter__(self):
return iter(self.collection)
def discard(self,item):
print "discarding {item}".format(item=str(item))
for index, value in enumerate(self.collection):
if value == item:
print "found {value}=={item}".format(value=value,item=item)
return self.collection.pop(index)
return False
class MyItemClass(object):
def __init__(self,value):
self.value=value
def __str__(self):
return '{value}'.format(value=self.value)
def __eq__(self,other):
if self.value == other.value:
return True
else:
return False
c1 = MyContainerClass()
c2 = MyContainerClass()
c2 += MyItemClass('item1')
c2 += MyItemClass('item2')
c2 += MyItemClass('item3')
c2 += MyItemClass('item4')
c2 += MyItemClass('item5')
print "c1 is : {c1}".format(c1=str(c1))
print "c2 is : {c2}".format(c2=str(c2))
for item in c2:
print "for got {item}".format(item=str(item))
c1 += c2.discard(item)
print "c1 is : {c1}".format(c1=str(c1))
print "c2 is : {c2}".format(c2=str(c2))
Производит этот вывод:
adding item1
adding item2
adding item3
adding item4
adding item5
c1 is : Empty
c2 is : item1, item2, item3, item4, item5
for got item1
discarding item1
found item1==item1
adding item1
for got item3
discarding item3
found item3==item3
adding item3
for got item5
discarding item5
found item5==item5
adding item5
c1 is : item1, item3, item5
c2 is : item2, item4
я уверен, что это что-то действительно очевидно, возможно сделать с помощью функции ITER, но я не могу видеть это на данный момент.
Конечно ... Так что добавление __getitem__ в класс контейнера и использование среза - самый чистый способ достичь этого? – PhilipDG
@PhilipDG: Лично я просто написал 'для элемента в кортеже (c2):'. Но если вы обычно делаете это для списка, это написать 'для элемента в c [:]' then yes, реализовать '__getitem__' для обработки срезов. Я думаю, это вопрос о том, как вы похожи на список «MyContainerClass». –