在类中使用next()函数

时间:2018-11-10 01:40:10

标签: python python-3.x

我有一堂课,可以使用矩阵中的概率来预测天气。矩阵很小:

weather = [
    [0.4,  0.3,  0.1,  0.05, 0.1,  0.05],
    [0.3,  0.4,  0.1,  0.1,  0.08, 0.02],
    [0.2,  0.3,  0.35, 0.05, 0.05, 0.05],
    [0.1,  0.2,  0.25, 0.3,  0.1,  0.05],
    [0.15, 0.2,  0.1,  0.15, 0.3 , 0.1 ],
    [0.1 , 0.2,  0.35, 0.1 , 0.05, 0.2 ]
]

每一行对应一种天气(按照上面给出的顺序),每一列是第二天发生一种天气(也按照上面给出的顺序)的概率。我写了一个班级,该班级计算出例如鉴于前一天天气晴朗,天气会下冰雹的概率。我把它做成一个迭代器,如下所示:

class Markov:
    def __init__(self):
        #Initialize Markov object
        self.weather = {'sunny':0, 'cloudy':1, 'rainy':2, 
                        'snowy':3, 'windy':4, 'hailing':5}
        self.dat = np.array([])
        self.previous_day = None
        self.following_day = None

    #load data
    def load_data(self, array):
        # implement here
        self.dat = array

    # Get probability of weather on following day given weather on #previous day
    def get_prob(self, previous_day, following_day):

        self.previous_day = previous_day
        self.following_day = following_day
        return self.dat[self.weather[previous_day]][self.weather[following_day]]

    def __iter__(self):
        return self

    #function I would like to write. 
    def get_weather_for_day(self, day):
        pass

    #Implement the next function which does most of the heavy lifting. 
    def __next__(self):
        outcome = ''.join(np.random.choice(a = list(self.weather.keys()), size = 1, p=self.dat[self.weather[self.following_day]]))
        self.following_day = self.previous_day
        return "The next day's weather is " + outcome

#Run the code
weather_today = Markov()
weather_today.load_data(weather)
print(weather_today.get_prob('sunny', 'hailing'))
next(weather_today)

#Output
"The next day's weather is rainy"

>next(weather_today)
"The next day's weather is windy"
>next(weather_today)
>"The next day's weather is sunny"

这很好,但对用户来说却很费力。如果我想在第10天返回天气怎么办?关于如何实现这一点的任何想法?我想要的方法是get_weather_for_day(self,day),其中day指定天数。

我的假设是我会在__next__中使用get_weather_for_day(self, day)函数,但不确定如何实现此功能?

简而言之,我想要的是以下输出:

weather_today = Markov()
weather_today.load_data(weather)
weather_today.get_weather_for_day(5)

#output
In 5 days, the weather will be snowy

1 个答案:

答案 0 :(得分:0)

当您的实例用作迭代器时(它将在for循环中,因为您只需在self中返回__iter__)。每次__next__迭代都会调用方法for

因此,您可以在for循环中直接使用实例,并通过具有可由enumerate提供的索引来控制迭代次数。除此之外,您可能希望在迭代之前将某些状态归零-如果是这样,请在__iter__内进行操作,然后再返回self

class Markov:
    ...
    get_weather_for_day(self, day):
         for daycount, prediction in enumerate(self):
             if daycount == day:
                  return prediction

如果您要(1)在调用此方法之前保留“ previous_day”状态,或者(2)在多线程或异步程序中使用此代码(例如,后端为在视图中使用的Web应用程序。

在这种情况下,您可以在进行迭代之前在函数内部以当前状态创建实例的副本

 from copy import copy

 class Markov:
    ...

    def __next__(self):
        outcome = ''.join(np.random.choice(a = list(self.weather.keys()), size = 1, p=self.dat[self.weather[self.following_day]]))
        self.following_day = self.previous_day
        return  outcome

    def __iter__(self):
         return copy(self)
    ...
    get_weather_for_day(self, day):

         for daycount, prediction in enumerate(iter(self)):
             if daycount == day:
                  return f"In {day} days the weather will be {prediction}!"

(啊,当然,您必须自己更改__next__的返回值,以便您可以按照此函数的要求格式化输出-)

相关问题