Pythonäquivalent von C ++ begin () und end () für benutzerdefinierte Klassen

Sag, du hast ein Wörterbuch, dessen Schlüssel ganze Zahlen sind Die Werte sind auch Wörterbücher, deren Schlüssel Strings sind und deren Werte numpy Arrays sind. Etwas wie:

custom = {1: {'a': np.zeros(10), 'b': np.zeros(100)}, 2:{'c': np.zeros(20), 'd': np.zeros(200)}} 

Ich habe diese benutzerdefinierte Datenstruktur ziemlich viel in den Code verwendet, und jedes Mal, wenn ich über jede der Zeilen in den numpy Arrays dieser Struktur iterieren muss, muss ich:

 for d, delem in custom.items(): for k, v in delem.items(): for row in v: print(row) 

Ist es möglich, dieses Verhalten in Funktionen à la C ++ zu verkapseln, wo man eigentlich benutzerdefinierte begin() und end() implementieren kann? Außerdem sollte der Iterator auch über die Schlüssel in den entsprechenden Wörterbüchern informiert werden. Ich stelle mir etwas vor:

 for it in custom: d, e, row = *it # then do something with these 

4 Solutions collect form web for “Pythonäquivalent von C ++ begin () und end () für benutzerdefinierte Klassen”

 import numpy as np custom = { 1: {'a': np.zeros(10), 'b': np.zeros(100)}, 2:{'c': np.zeros(20), 'd': np.zeros(200)} } my_gen = ( (key, subkey, np_array) for (key, a_dict) in custom.items() for subkey, np_array in a_dict.items() ) for key, subkey, np_array in my_gen: print(key, subkey, np_array) --output:-- 1 b [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 1 a [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 2 d [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 2 c [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.] 

Oder du könntest deine Datenstruktur in etwas umsetzen, das für deine Zwecke nützlicher ist:

 import numpy as np custom = { 1: {'a': np.zeros(10), 'b': np.zeros(100)}, 2:{'c': np.zeros(20), 'd': np.zeros(200)} } #Create a *list* of tuples: converted_data = [ (np_array, subkey, key) for (key, a_dict) in custom.items() for subkey, np_array in a_dict.items() ] for np_array, subkey, key in converted_data: print(key, subkey, np_array) 

Erstellen eines benutzerdefinierten Iterators:

 class Dog: def __init__(self, data): self.data = data self.max = len(data) self.index_pointer = 0 def __next__(self): index = self.index_pointer if index < self.max: current_val = self.data[index] self.index_pointer += 1 return current_val else: raise StopIteration class MyIter: def __iter__(self): return Dog([1, 2, 3]) for i in MyIter(): print(i) --output:-- 1 2 3 

__iter__() nur ein Objekt zurückgeben, das eine __next__() Methode implementiert, so dass man diese beiden Klassen wie __next__() kombinieren kann:

 class MyIter: def __init__(self, data): self.data = data self.max = len(data) self.index_pointer = 0 def __iter__(self): return self #I have a __next__() method, so let's return me! def __next__(self): index = self.index_pointer if index < self.max: current_val = self.data[index] self.index_pointer += 1 return current_val else: raise StopIteration for i in MyIter([1, 2, 3]): print(i) --output:-- 1 2 3 

Eine komplexere __next__() Methode:

 import numpy as np class CustomIter: def __init__(self, data): self.data = data self.count = 0 def __iter__(self): return self def __next__(self): count = self.count self.count += 1 if count == 0: #On first iteration, retun a sum of the keys return sum(self.data.keys()) elif count == 1: #On second iteration, return the subkeys in tuples subkeys = [ a_dict.keys() for a_dict in self.data.values() ] return subkeys elif count == 2: #On third iteration, return the count of np arrays np_arrays = [ np_array for a_dict in self.data.values() for np_array in a_dict.values() ] return len(np_arrays) else: #Quit after three iterations raise StopIteration custom = { 1: {'a': np.zeros(10), 'b': np.zeros(100)}, 2:{'c': np.zeros(20), 'd': np.zeros(200)} } for i in CustomIter(custom): print(i) --output:-- 3 [dict_keys(['b', 'a']), dict_keys(['d', 'c'])] 4 

Es gibt mehrere Möglichkeiten, dies zu tun. yield kann die einfachste sein, wie es das schwere Heben des Aufbaus einer Interator-Klasse für Sie tut.

 def custom_dict_iter(custom): for d, delem in custom.items(): for k, v in delem.items(): for row in v: yield d, k, row for d, k, row in custom_dict_iter(my_custom_dict): print(d, k, row) 

Schauen Sie sich das Iteratorprotokoll an – das ähnelt Java's Iterable oder C # 's IEnumerable als C ++' s Anfang / Ende. Sie können es einfacher definieren, indem Sie die __iter__ Methode als Generator definieren .

Das einzige, was du brauchst, musst du deinen custom haben, hat seine eigene Klasse mit diesen Methoden anstatt ein einfaches Wörterbuch, aber ich nehme an, das gilt auch in C ++.

Als pythonischer Weise können Sie ein verschachteltes Listenverständnis verwenden, das bei C-Sprachgeschwindigkeit im Interpreter auftritt:

 >>> [[(i,key,t) for t in value] for i,j in custom.items() for key,value in j.items()] 

Und wenn du einen Iterator bekommen möchtest, kannst du statt des Listenverständnisses einen Generatorausdruck verwenden.

 >>> ([(i,key,t) for t in value] for i,j in custom.items() for key,value in j.items()) 
  • Überspringen Sie mehrere Iterationen in der Schleifenpythonschlange
  • Umwandlung für Loops zu Loops in Python
  • Finden der zweitkleinsten Zahl mit Schleifen in Python
  • Python - `Pause 'aus allen Schleifen
  • Trialhandler und Zeitmessung in der Psychopie
  • Python: Wie bekomme ich die Eingabe von der Konsole, während eine Endlosschleife läuft?
  • Python - Vorherige und nächste Werte innerhalb einer Schleife
  • Python-Skript, das eine iterierende Google-Suche ausführt und die Top-Ergebnisse und Links druckt
  • Python-Schleife frühzeitig
  • Wenn sonst statement nicht nach dem elif korrekt folgt [duplizieren]
  • Mehr Pythonic / Pandorable Ansatz zum Looping über eine Pandas Serie
  • Python ist die beste Programmiersprache der Welt.