Genorator Funtion卡在第一个if子句中,有限状态机[duplicate]

问题描述 投票:0回答:1

我正在尝试编写一个函数,它将使我从一种状态进入下一种状态,直到达到最终状态。当我用:

运行它时

new_location = change_location()

下一个(新位置)

第一次迭代有效,但是一旦进入while循环,它就永远不会离开第一个if子句,并且也与先前的位置没有任何联系。我正在尝试从一种状态迁移到另一种状态,其中状态为e(仅在开始时出现一次),da,dr,f,s和ch(和ex)(仅出现在末尾!)。它们遵循的路径始终以“至”分隔。

我还尝试过在每个子句后添加yield语句,但是仍然没有遵循所需的模式。 p是将采用每条到达下一个位置的路径的概率权重。

import numpy as np

def change_location():
        location = np.random.choice(['etof', 'etoda', 'etos', 'etodr'], 
                                          p =[0.377435, 0.287576, 0.181463, 0.153526])
        yield location
        while True:
            print(location)
            if location == 'etoda' or 'datoda' or 'drtoda'or 'ftoda' or 'stoda':
                location = np.random.choice(a=['datoch', 'datoda', 'datodr', 'datof', 'datos'], 
                p =[0.100000,0.740000,0.060000,0.050000,0.050000])
            elif location == 'etodr' or 'drtodr' or 'datodr' or 'ftodr' or 'stodr':
                location = np.random.choice(a=['drtoch', 'drtoda', 'drtodr','drtof', 'drtos'], 
                p =[0.215710, 0.010899, 0.598499, 0.087909,0.086983])
            elif location == 'etof' or 'datof' or 'drtof' or 'ftof' or 'stof':
                location = np.random.choice(a=['ftoch', 'ftoda', 'ftodr', 'ftof', 'ftos'], 
                p =[0.201605,0.095924,0.054847,0.596947,0.050677])
            elif location == 'etos' or 'datos' or 'drtos' or 'ftos' or 'stos':
                location = np.random.choice(a=['stoch', 'stoda', 'stodr', 'stof', 'stos'], 
                p =[0.150685,0.193214,0.163109,0.090953,0.402039])
            else:
                location = 'chtoex'
                break
            yield location
python numpy random generator choice
1个回答
0
投票

第一件事当然是注释中指出的错误。我还想指出,每当您看到包含多个if:s和elif:s的代码,并且都重复一个模式时,很难发现并纠正错误。有更好的方法。

分别构造数据,并使用for和else保持代码精简。

import numpy as np

location_mappings = [
    {
        'from': [None],
        'to': ['etof', 'etoda', 'etos', 'etodr'],
        'p': [0.377435, 0.287576, 0.181463, 0.153526],
    },
    {
        'from': ['etoda', 'datoda', 'drtoda', 'ftoda', 'stoda'],
        'to': ['datoch', 'datoda', 'datodr', 'datof', 'datos'],
        'p': [0.100000,0.740000,0.060000,0.050000,0.050000],
    },
    {
        'from': ['etodr', 'drtodr', 'datodr', 'ftodr', 'stodr'],
        'to': ['drtoch', 'drtoda', 'drtodr','drtof', 'drtos'],
        'p': [0.215710, 0.010899, 0.598499, 0.087909,0.086983],
    },
    {
        'from': ['etof', 'datof', 'drtof', 'ftof', 'stof'],
        'to': ['ftoch', 'ftoda', 'ftodr', 'ftof', 'ftos'],
        'p': [0.201605,0.095924,0.054847,0.596947,0.050677],
    },
    {
        'from': ['etos', 'datos', 'drtos', 'ftos', 'stos'],
        'to': ['stoch', 'stoda', 'stodr', 'stof', 'stos'],
        'p': [0.150685,0.193214,0.163109,0.090953,0.402039],
    },
]
end_location = 'chtoex'

def change_location():
    location = None
    while location != end_location:
        for mapping in location_mappings:
            if location in mapping['from']:
                location = np.random.choice(mapping['to'], p=mapping['p'])
                break
        else:  # If break was not called
            location = end_location
        yield location
© www.soinside.com 2019 - 2024. All rights reserved.