Python Equivalent Of C++ Begin() And End() For Custom Classes
Solution 1:
There are multiple ways to do this. yield
may be the simplest as it does the heavy lifting of building an interator class for you.
def custom_dict_iter(custom):
ford, delem in custom.items():
fork, v in delem.items():
forrowin v:
yield d, k, row
ford, k, row incustom_dict_iter(my_custom_dict):
print(d, k, row)
Solution 2:
Look up the iterator protocol - this is more similar to Java's Iterable
or C#'s IEnumerable
than C++'s begin/end. You can define it more easily by defining the __iter__
method as a generator.
The only thing is, you'd need to make your custom
have its own class with these methods rather than a plain dictionary, but I assume that's also true in C++.
Solution 3:
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.]
Or, you could reconstitute your data structure into something that is more useful for your purposes:
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)
Creating a custom iterator:
classDog:
def__init__(self, data):
self.data = data
self.max = len(data)
self.index_pointer = 0def__next__(self):
index = self.index_pointer
if index < self.max:
current_val = self.data[index]
self.index_pointer += 1return current_val
else:
raise StopIteration
classMyIter:
def__iter__(self):
return Dog([1, 2, 3])
for i in MyIter():
print(i)
--output:--
123
__iter__()
just needs to return an object that implements a __next__()
method, so you can combine those two classes like this:
classMyIter:
def__init__(self, data):
self.data = data
self.max = len(data)
self.index_pointer = 0def__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 += 1return current_val
else:
raise StopIteration
for i in MyIter([1, 2, 3]):
print(i)
--output:--
123
A more complex __next__()
method:
import numpy as np
classCustomIter:
def__init__(self, data):
self.data = data
self.count = 0def__iter__(self):
return self
def__next__(self):
count = self.count
self.count += 1if count == 0: #On first iteration, retun a sum of the keysreturnsum(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()
]
returnlen(np_arrays)
else: #Quit after three iterationsraise 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
Solution 4:
As a more pythonic way you can use a nested list comprehension which performs at C language speed inside the interpreter:
>>> [[(i,key,t) fortin value] fori,j in custom.items() forkey,value in j.items()]
And if you want to get an iterator you can use a generator expression instead of list comprehension.
>>> ([(i,key,t) fortin value] fori,j in custom.items() forkey,value in j.items())
Post a Comment for "Python Equivalent Of C++ Begin() And End() For Custom Classes"