我对python和编程都是新手,所以我很迷茫。我已经编写了一个“Node”类(如下文底部所示),它实例化了一个二叉搜索树和几个方法,如insert()和elements()(通过按顺序横切树返回元素列表)。我应该使这个类是可迭代的:“iter__(self)应该返回一个NodeIterator,它按照排序顺序从树中返回元素。修改树不应该修改现有的迭代器。”我现在正试图通过在类中插入以下代码来实现这一点:
def __iter__(self):
x=self.copy()
x.i=0
return x
def next(self):
lst=x.elements()
#??? No idea what to do from here.
我定义了x=self.copy()以试图覆盖修改树不应该修改迭代器的事实,但我不知道这是不是正确的想法。下面是我的节点类,其中一个方法使用了装饰器:
def depth(old_f):
''' Write a decorator that overrides the standard behavior of
a function that returns True or False and instead returns
0 for False or n for number of recursive calls needed to
return True.
'''
def new_f(*args):
res = old_f(*args)
if res is True:
return 1
elif res:
return 1 + res
else:
return 0
return new_f
Class Node(object):
'''
Modify your Node class from homework 4 as follows:
Two elements that compare equal shouldn't be allowed in the Tree. If a
copy is inserted, throw an AlreadyExistsException with the error
message "Element [x] is already in the tree".
__iter__(self) should return a NodeIterator, which returns elements from
the tree in sorted order. Modifying the tree should not modify
existing iterators.
'''
count = 0
def __init__(self, val, left=None, right=None):
self.Val = val
self.Left = left
self.Right = right
Node.count += 1
def __repr__(self):
'''If the node has neither a left nor right child,
simply return Node(val). Else, return Node(x, val, y),
where x and y are recursive calls that return the
left and right children, respectively.
'''
if self.Left is None and self.Right is None:
return "Node({})".format(self.Val)
else:
return "Node({}, {}, {})".format(self.Left, self.Val, self.Right)
@depth
def search(self, element):
''' Finds whether a given element is in the tree.
Returns True if the element is found, else returns False.
Give it the depth decorator you defined earlier.
'''
if element == self.Val:
return True
elif self.Val > element and self.Left is not None:
return self.Left.search(element)
elif self.Val < element and self.Right is not None:
return self.Right.search(element)
else:
return False
def insert(self, element):
''' Insert an element into a binary search tree rooted
at this Node. After insertion, return the modified node.
Our implementation will allow duplicate nodes. The left subtree
should contain all elements <= to the current element, and the
right subtree will contain all elements > the current element.
'''
if element <= self.Val:
if self.Left is not None:
self.Left.insert(element)
else:
self.Left = Node(element)
else:
if self.Right is not None:
self.Right.insert(element)
else:
self.Right = Node(element)
return self
def elements(self):
''' Return a list of the elements visited in an inorder traversal:
http://en.wikipedia.org/wiki/Tree_traversal
Note that this should be the sorted order if you've inserted all
elements using your previously defined insert function.
'''
if self.Left is None and self.Right is None:
return [self.Val]
elif self.Left is None and self.Right is not None:
return [self.Val] + self.Right.elements()
elif self.Left is not None and self.Right is None:
return self.Left.elements() + [self.Val]
else:
return self.Left.elements() + [self.Val] + self.Right.elements()
不要在类上定义next
;这使得实例成为迭代器(它必须直接迭代对象),而您想要的是一个不是迭代器的iterable。为此,定义__iter__
并让它在对象的副本上返回一个全新的迭代器。
由于您已经有了一个elements
方法,可以有效地快照您的节点
,因此使用它来创建快照迭代器并不难;复制结构是没有意义的,因为您只是按顺序迭代,而elements
可以为您完成这项工作(并且在启动快照时使用更少的内存)。通常,我只需要使__iter__
成为生成器函数,例如:
def __iter__(self):
# Python 3 simple version
yield from self.elements()
# Python 2 or 3 version
for x in self.elements():
yield x
但是由于您的分配调用了一个特殊的NodeIterator
类,所以这是不行的。为此,您需要创建一个新类(可能在现有的node
类中定义,以便为其命名):
class Node(object):
...
class NodeIterator(object):
def __init__(self, node):
self.it = iter(node.elements())
def __iter__(self):
return self
def next(self):
return next(self.it)
__next__ = next # Makes code work on Py2 and Py3 without modification
def __iter__(self):
return NodeIterator(self)
您可以理解为什么我通常不需要使用特殊类,因为__iter__
的生成器函数(使用yield
魔术的函数)要简单得多,但这是基本结构。您可以在Python wiki上了解更多关于迭代器的信息,或者在Pythoncollections
ABC文档中了解基本接口的信息。
问题内容: 假设我有一个整数集,并且我想增加集合中的每个整数。我该怎么做? 我可以在迭代时添加和删除集合中的元素吗? 在迭代原始集合时,是否需要创建一个新集合以将元素“复制并修改”到其中? 编辑:如果集合中的元素是不可变的呢? 问题答案: 您可以在迭代期间使用Iterator对象安全地从集合中删除;尝试在迭代时通过其API修改集合会破坏迭代器。Set类通过getIterator()提供一个迭代器。
我有一个json blob,如下所示: 这只是一个在这里发布的例子。在这个例子中,我们看到它提供了一个学校每年发生的所有事件的列表,该列表是一个累积列表,即上一年的事件也会被追加。我们知道的是,每年的活动都将以“会议开始”活动开始。我想通过这件事,以最新的一系列事件结束。请忽略事件名称中的时间戳或年份,它们只是示例,我在现实世界中没有此类信息。我需要的最终结果是: 所以,我想保留从“会话开始”事件
问题内容: 我知道您不应在遍历列表时添加/删除项目。但是,如果不更改列表长度,是否可以修改要迭代的列表中的项目? 还是应该迭代列表索引?像那样: 问题是:以上两种方式都是允许的,还是只有第二种是没有错误的? 如果答案是肯定的,以下代码段是否有效? UPD。我想在python文档中看到“允许这些操作”而不是某人的假设。 问题答案: 可以这么说,您 不是在 修改列表。您只是在修改列表中的元素。我不认为
问题内容: 上面的python代码使输出与预期的完全不同。我想循环播放项目,以便在循环播放时可以跳过某个项目。 问题答案: 该代码试图在迭代列表时修改列表。我在任何情况下都不会这样做。 你可以使用运算符跳过列表中的每三个项目。 关于我的示例的其他要点与中的新语法有关。 我使用列表推导定义t,因为它在中有效(请参见下文) t是中的函数 现在,的行为类似于,但它适用于任意大小的值。后者不再存在。
问题内容: 假设我们有一个Python字典,我们正在像这样迭代它: (并且仅仅是一些黑盒转换。) 换句话说,我们尝试在使用对其进行迭代的同时向其中添加/删除项目。 这个定义好吗?您能否提供一些参考来支持您的答案? (很明显,如果损坏了该如何解决,所以这不是我所追求的角度。) 问题答案: 在python文档页面(针对2.7)上明确提到了 使用而添加或删除字典条目可能会产生一种或无法遍历所有条目。 对
我对java相当陌生,实际上我正在编写一个键盘记录器,并让它定期写入文件。每当用户按下某个键时,它都会实例化一个NativeKeyEvent,该事件调用“param string()”并将信息作为字符串添加到下面的arraylist中... 然后,在每一个间隔,字符串数组被传递,并被写入下面的TimerTask线程中的文件。 行'str=iterator.next().tostring();‘然后