假设你有一个字典,其键是整数.值也是字典,其键是字符串,其值是numpy数组.
就像是:
custom = {1: {'a': np.zeros(10), 'b': np.zeros(100)}, 2:{'c': np.zeros(20), 'd': np.zeros(200)}}
我一直在代码中使用这个自定义数据结构,每次我需要迭代这个结构的numpy数组中的每一行时,我必须这样做:
for d, delem in custom.items():
for k, v in delem.items():
for row in v:
print(row)
是否可以将此行为封装在可以实际实现自定义begin()和end()的函数中?此外,迭代器还应该包含有关其相应词典中的键的信息.我想象的是:
for it in custom:
d, e, row = *it
# then do something with these
最佳答案
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.]
或者,您可以将数据结构重构为对您的目的更有用的内容:
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)
创建自定义迭代器:
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 __()只需要返回一个实现__next __()方法的对象,这样就可以将这两个类组合起来:
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
一个更复杂的__next __()方法:
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