2 回答

TA貢獻(xiàn)1784條經(jīng)驗(yàn) 獲得超8個贊
list您可以通過使用適當(dāng)?shù)姆椒▽?shí)現(xiàn)對其進(jìn)行子類化來自定義行為,remove當(dāng)被刪除的索引小于當(dāng)前迭代器索引時,該方法會減少迭代器指向的索引:
from weakref import WeakSet
class IterList:
def __init__(self, lst):
self.list = lst
self.index = 0
def __next__(self):
if self.index == len(self.list):
raise StopIteration
value = self.list[self.index]
self.index += 1
return value
class List(list):
iterators = WeakSet()
def __iter__(self):
iterator = IterList(self)
self.iterators.add(iterator)
return iterator
def remove(self, item):
index = super().index(item)
for iterator in self.iterators:
if index < iterator.index:
iterator.index -= 1
del self[index]
以便:
container = List((1, 2, 3, 4))
for i in container:
if i == 2:
container.remove(1)
for j in container:
print(i, j)
輸出:
1 1
1 2
1 3
1 4
2 2
2 3
2 4
3 2
3 3
3 4
4 2
4 3
4 4

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超10個贊
您要詢問的行為是所涉及的迭代器的實(shí)現(xiàn)細(xì)節(jié)。正如您所注意到的,該list_iterator類型使用內(nèi)部索引,因此刪除已訪問的元素會導(dǎo)致問題,因?yàn)樗鼤牧斜碇兴泻罄m(xù)值的索引。
我的建議是您實(shí)際上并沒有從列表中刪除任何值。相反,將它們添加到另一個容器中,也許是一個set(如果它們是可散列的)。這假設(shè)值是唯一的。但如果不是,您可能會在使用任何方法從列表中刪除它們時遇到問題。
container = [1, 2, 3, 4]
removed = set()
for i in container:
if i not in removed: # skip values that have been "removed"
print(i)
if i == 2:
removed.add(1) # since we've already visited 1, this has no real effect
removed.add(3) # this does work though, we won't print the 3
container.append(8) # additions of new elements work as normal
正如評論所暗示的那樣,該循環(huán)帶有 print out 1、2、4和8.
添加回答
舉報