2016-10-28 2 views
2
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 

die Funktion einen Satz und gibt eine ListeKlasse, die über einen Satz iterieren nimmt

der Satz immer

s = {1, 2, 4, 8, 16}

zum Beispiel:

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 

Aber wenn meine Funktion nimmt

[next(i), next(i), s.remove(8), next(i), next(i), s.add(32), next(i)] 

sollte es

[1, 2, None, 4, 16, None, 32] 

Aber anstatt drucken, druckt es:

[1, 2, None, 4, 8, None, 16] 

kann mir jemand sagen, wie man es beheben?

Dank

posted ich den Fehler, den ich unten habe zu verstehen zu helfen:

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] 
+1

Der Iterator mehr, nachdem Sie etwas entfernen nicht gültig ist. –

+0

aber wie kann ich es beheben? – zhangdi

+0

kann mir jemand helfen, es zu reparieren? – zhangdi

Antwort

0

Die sorted() Funktion das Argument sortiert und gibt eine Liste. Das Ändern der Eingabemenge wirkt sich nicht auf die sortierte Liste aus.

Wenn der Iterator Änderungen an der ursprünglichen Menge widerspiegeln soll, muss der Iterator den Status der Menge bei jeder Iteration überprüfen und entsprechend reagieren.

0

Wenn Sie sorted verwenden, erstellen Sie eine sortierte Liste aus dem Satz. Diese Liste hat keine Verbindung zu dem ursprünglichen Set, aus dem sie erstellt wurde, und zeigt keine Änderungen an diesem Set an. Sie müssen die Änderungen selbst verfolgen, während Sie die Elemente in sortierter Reihenfolge durchlaufen.

Verfolgen von entfernten Elementen ist einfach: Überprüfen Sie einfach, ob das aktuelle Element noch im Originalsatz ist. Den Überblick über neue Elemente zu behalten, ist ein bisschen komplexer. Sie können das heapq-Modul verwenden und eine heap aus dem Satz erstellen, anstatt einer sortierten Liste, dann können Sie diesem Haufen neue Elemente hinzufügen, während Sie ihn iterieren. Um neue Elemente zu finden, erstellen Sie eine Kopie des ursprünglichen Satzes und vergleichen Sie die beiden in jeder Iteration. Außerdem müssen Sie gemäß Ihren Testfällen überprüfen, ob das aktuelle Element kleiner als das vorherige ist, und es in diesem Fall überspringen.

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) 

Dies funktioniert für alle Testfälle (Reinitialisierung s und i nicht dargestellt):

>>> 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] 
Verwandte Themen