Python 在集合上迭代的类
函数获取一个集合并返回一个列表 布景总是很好 s={1,2,4,8,16} 例如:Python 在集合上迭代的类,python,iterable,Python,Iterable,函数获取一个集合并返回一个列表 布景总是很好 s={1,2,4,8,16} 例如: class Ordered: def __init__(self,aset): self.aset = aset def __iter__(self): for v in sorted(self.aset): # iterate over list of values returned by sorted yield v 但当我的功能发挥作
class Ordered:
def __init__(self,aset):
self.aset = aset
def __iter__(self):
for v in sorted(self.aset): # iterate over list of values returned by sorted
yield v
但当我的功能发挥作用时
s = {1, 2, 4, 8, 16}
i = iter(Ordered(s))
print(next(i))
print(next(i))
s.remove(8)
print(next(i))
s.add(32)
print(next(i))
print(next(i))
it should prints 1 2 4 16 32
应该打印出来
[next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)]
但相反,它打印:
[1, 2, None, 4, 16, None, 32]
有人能告诉我怎么修吗?谢谢
我在下面发布了我得到的错误,以帮助理解:
[1, 2, None, 4, 8, None, 16]
函数对参数进行排序并返回一个列表。修改输入集不会影响排序列表
如果您希望迭代器反映对原始集合的更改,迭代器需要在每次迭代时检查集合的状态并做出相应的响应。使用排序的
时,您需要从集合中创建一个排序列表。该列表与创建它的原始集没有连接,并且不会反映对该集的任何更改。您必须自己跟踪更改,同时按排序顺序迭代元素
跟踪删除的元素很简单:只需检查当前元素是否仍在原始集合中。跟踪新元素有点复杂。您可以使用该模块并从集合中创建一个新的堆,而不是一个排序列表,然后您可以在迭代堆的同时向该堆添加新元素。要查找新元素,请创建原始集合的副本,并在每次迭代中比较两者。另外,根据您的测试用例,您必须检查当前元素是否比前一个元素小,在本例中跳过它
39 *Error: Failed [next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)] == [1, 2, None, 4, 16, None, 32]
evaluated: [1, 2, None, 4, 8, None, 16] == [1, 2, None, 4, 16, None, 32]
42 *Error: [next(i), next(i), next(i), s.add(3), next(i), s.add(10), s.add(32), next(i), next(i), next(i)] raised exception; unevaluated: [1, 2, 4, None, 8, None, None, 10, 16, 32]
46 *Error: Failed [next(i), s.remove(2), s.remove(4), s.remove(8), next(i)] == [1, None, None, None, 16]
evaluated: [1, None, None, None, 2] == [1, None, None, None, 16]
49 *Error: Failed [next(i), s.remove(2), next(i), s.remove(4), s.remove(8), next(i)] == [1, None, 4, None, None, 16]
evaluated: [1, None, 2, None, None, 4] == [1, None, 4, None, None, 16]
删除某些内容后,迭代器不再有效。但是我如何修复它?有人能帮我修复它吗?
import heapq
class Ordered:
def __init__(self,aset):
self.aset = aset
def __iter__(self):
# memorize original elements
known = set(self.aset)
last = None
# create heap
heap = list(self.aset)
heapq.heapify(heap)
# yield from heap
while heap:
v = heapq.heappop(heap)
if (v in self.aset and # not removed
(last is None or last < v)): # not smaller than last
yield v
last = v
# in case of new elements, update the heap
diff = self.aset - known
if diff:
for x in self.aset - known:
heapq.heappush(heap, x)
known = set(self.aset)
>>> s = {1, 2, 4, 8, 16}
>>> i = iter(Ordered(s))
>>> [next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)]
[1, 2, None, 4, 16, None, 32]
>>> [next(i), next(i), next(i), s.add(3), next(i), s.add(10), s.add(32), next(i), next(i), next(i)]
[1, 2, 4, None, 8, None, None, 10, 16, 32])
>>> [next(i), s.remove(2), s.remove(4), s.remove(8), next(i)]
[1, None, None, None, 16]
>>> [next(i), s.remove(2), next(i), s.remove(4), s.remove(8), next(i)]
[1, None, 4, None, None, 16]