Python相当于自定义类的C begin()和end()

假设你有一个字典,其键是整数.值也是字典,其键是字符串,其值是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
点赞