1 回答

TA貢獻1836條經驗 獲得超13個贊
下一項的 dunder 方法不是__next__,__next并且您似乎缺少在迭代時實際在列表中移動的代碼。
我使用的常規方法是在類型中使用一個單獨的迭代器類來完成繁重的工作。此外,設置列表的方式也使得元素類的想法變得可?。ㄈ绻褂肞ython列表,則不需要這樣做,但是,由于您需要一個and“指針”,所以最好將其作為單獨的item列表next)班級)。
讓我們首先創建帶有封閉項目類的列表類:
class MyList:
# Single element in the list.
class MyListElem:
def __init__(self, item, link_from = None, link_to = None):
# Set data, link from previous and to next if specified.
self._item = item
self._next = link_to
if link_from is not None:
link_from.change_link(self)
def change_link(self, item):
self._next = item
元素類有兩種方法,第一種方法根據需要創建帶有鏈接的元素。目前(見MyList.add()下文),to鏈接始終是None因為我們僅附加到列表中。
類似地,from鏈接要么是None當前尾部,要么是當前尾部,具體取決于我們是將第一個元素還是后續元素添加到列表中。
這些參數主要是為了滿足以后能夠插入列表中任意位置的可能性。
接下來是迭代器類,也是列表類的一部分:
# Iterator over the list.
class MyListIter:
def __init__(self, head):
# Start at the head.
self._curr = head
def __iter__(self):
# To iterate over the iterator rather than collection.
return self
def __next__(self):
# Check more left, advance to next and return current.
if self._curr is None:
raise StopIteration
ret_val = self._curr._item
self._curr = self._curr._next
return ret_val
這相對簡單,初始化器只是設置我們以便第一次調用將返回頭部。該__iter__調用允許您從集合中檢索迭代器,然后對其進行迭代,而不是直接在集合上進行迭代。區別在于:
for iter in object: # iterate over object
pass
iter = object.__iter__() # iterate over iterator
for iter2 in iter:
pass
有關為什么需要這樣做的更多詳細信息,請參閱此處。
調用__next__是迭代器的“核心”。如果迭代器完成,它會引發異常。否則,它會在前進到下一個值后返回當前值。
然后是列表類本身,一個非常簡單的類,只允許追加到末尾,不允許刪除,并且有一個迭代器來處理它:
# The list itself.
def __init__(self):
# Empty list to start with.
self._head = None
self._tail = None
def add(self, val):
# Append to the end of the list.
if self._head is None:
self._head = self.MyListElem(val)
self._tail = self._head
else:
self._tail = self.MyListElem(val, self._tail)
def __iter__(self):
return self.MyListIter(self._head)
這真的很容易(嗯,相對容易)。以下測試代碼顯示了它的實際效果:
x = MyList()
x.add(12345)
x.add(42)
x.add("Hello")
x.add([1, 2, 3])
for i in x:
print(i)
正如預期的那樣,其輸出是:
12345
42
Hello
[1, 2, 3]
添加回答
舉報