如何使 MyList 可迭代?
How can I make MyList iterable?
我想创建一个行为类似于列表的 class。挑战是在不使用列表或字典的情况下做到这一点。到目前为止,我已经创建了一个节点 class,如下所示:
class Node:
def __init__(self, value=None):
self.next = None
self.last = None
self.value = valor
def __repr__(self):
return self.value
和MyList
class 这基本上是一个节点链,有一个头节点和一个尾节点。问题是,我想让它可迭代,这样我就可以 运行 for 了。我搜索了 iter 和 next 是如何工作的,并得出了这样的结果:
class MyList:
def __init__(self):
self.head = None
self.tail = None
def __iter__(self):
return self
def __next__(self):
if self.head:
if self.head.next:
self.head = self.head.next
return self.head.last
aux = self.head
self.head = None
return aux
raise StopIteration
它有效,但它显然删除了 MyList
中的数据,因此我无法再次使用它。关于如何在不弄乱对象内部信息的情况下获得相同结果的任何建议?
您需要在 class 中添加一个 "current" 标记以指示迭代当前指向的节点。像这样:
class MyList:
def __init__(self):
self.head = None
self.tail = None
self.current = self.head
def __iter__(self):
return self
def __next__(self):
if self.current is not None:
it = self.current
self.current = self.current.next
return it
raise StopIteration
目前,您的列表不区分其头部和当前迭代位置,但这是两个完全不同的概念。
当然,如果你这样做,同一个 MyList 上的所有迭代都将是 "linked",所以如果你这样做:
x = MyList(1, 2, 3, 4)
for item in x:
print(x)
if item == 2:
break
for item in x:
print(x)
然后第二次迭代将从第一次停止的地方开始。如果您不想要这种行为,则必须创建一个单独的迭代器 class,并让 MyList.__iter__
return 成为它的一个实例,而不是 self
。如果你从__iter__
returnself
,那么对象不能有多个独立的迭代进行,因为迭代状态作为被迭代的数据存储在对象中。
注意迭代器协议只要求the container's __iter__
returns一个迭代器;您还可以将 __iter__
实现为生成器,而不是返回实例本身:
def __iter__(self):
node = self.head
while node is not None:
yield node
node = node.next
我想创建一个行为类似于列表的 class。挑战是在不使用列表或字典的情况下做到这一点。到目前为止,我已经创建了一个节点 class,如下所示:
class Node:
def __init__(self, value=None):
self.next = None
self.last = None
self.value = valor
def __repr__(self):
return self.value
和MyList
class 这基本上是一个节点链,有一个头节点和一个尾节点。问题是,我想让它可迭代,这样我就可以 运行 for 了。我搜索了 iter 和 next 是如何工作的,并得出了这样的结果:
class MyList:
def __init__(self):
self.head = None
self.tail = None
def __iter__(self):
return self
def __next__(self):
if self.head:
if self.head.next:
self.head = self.head.next
return self.head.last
aux = self.head
self.head = None
return aux
raise StopIteration
它有效,但它显然删除了 MyList
中的数据,因此我无法再次使用它。关于如何在不弄乱对象内部信息的情况下获得相同结果的任何建议?
您需要在 class 中添加一个 "current" 标记以指示迭代当前指向的节点。像这样:
class MyList:
def __init__(self):
self.head = None
self.tail = None
self.current = self.head
def __iter__(self):
return self
def __next__(self):
if self.current is not None:
it = self.current
self.current = self.current.next
return it
raise StopIteration
目前,您的列表不区分其头部和当前迭代位置,但这是两个完全不同的概念。
当然,如果你这样做,同一个 MyList 上的所有迭代都将是 "linked",所以如果你这样做:
x = MyList(1, 2, 3, 4)
for item in x:
print(x)
if item == 2:
break
for item in x:
print(x)
然后第二次迭代将从第一次停止的地方开始。如果您不想要这种行为,则必须创建一个单独的迭代器 class,并让 MyList.__iter__
return 成为它的一个实例,而不是 self
。如果你从__iter__
returnself
,那么对象不能有多个独立的迭代进行,因为迭代状态作为被迭代的数据存储在对象中。
注意迭代器协议只要求the container's __iter__
returns一个迭代器;您还可以将 __iter__
实现为生成器,而不是返回实例本身:
def __iter__(self):
node = self.head
while node is not None:
yield node
node = node.next