簡體   English   中英

如何重構此代碼片段以提高效率?

[英]How can I refactor this code snippet to make it more efficient?

我正在嘗試根據博弈論制作一個動作矩陣。 因此,如果兩個人相遇,他們可以共享,或者一個偷,或者兩個偷,等等。

我所擁有的輪廓看起來像這樣(不是整個矩陣,只是為了讓您了解):

if first_agent.type == "AlwaysShare" and second_agent.type == "AlwaysShare":
    pass
elif first_agent.type == "AlwaysSteal" and second_agent.type == "AlwaysShare":
    pass
elif first_agent.type == "AlwaysShare" and second_agent.type == "AlwaysSteal":
    pass

顯然,這是非常低效的並且容易出錯。 我該如何優化它,以便有效地管理矩陣的交互?

您可以構建一個查找矩陣。

lookup = {
    "AlwaysShare": {
        "AlwaysShare": action1,
        "AlwaysSteal": action2,
    },
    "AlwaysSteal": {
        "AlwaysShare": action3,
        "AlwaysSteal": action4,
    },
}

action = lookup[first_agent.type][second_agent.type]
action()

當我遇到有多個選項的情況時,我喜歡制作一個處理不同可能性的函數字典。 鍵是編碼和標准化的輸入。 在您的情況下,您可以生成這樣的密鑰:

def key(first_agent, second_agent):
    key = [first_agent.type, second_agent.type]
    key.sort()
    return tuple(key)

然后你的字典看起來像這樣:

def handle_share():
    pass

def handle_one_steal():
    pass

def handle_both_steal():
    pass

# Etc.

action_map = {
    ('AlwaysShare', 'AlwaysShare'): handle_share,
    ('AlwaysShare', 'AlwaysSteal'): handle_one_steal,
    ('AlwaysSteal', 'AlwaysSteal'): handle_both_steal,
}

如果您仔細確定函數的范圍(例如,根據需要使它們成為方法或嵌套函數),您可以微調您可能需要它們具有的任何副作用。

現在您可以將if -block 替換為以下內容:

action_map[key(first_agent, second_agent)]()

如果您考慮到合適的默認值或無操作,並且不想為潛在的未知交互獲取KeyError ,請改用action_map.get

這樣做的好處是您可以輕松添加新的交互:只需實現一個函數並將其注冊到字典中。 想找第三方代理? 使key接受*args而不是固定數量的代理。 需要定義另一種類型的代理? 沒問題。 等等。

根據您的用例,首先檢查匹配與不匹配可能是有意義的:

if first_agent.type == second_agent.type:
    action = first_agent.type
    if action == "AlwaysShare":
        do_something()
    elif action == "AlwaysSteal":
        do_something_else()

else:
    whatever_happens_if_mismatch()

我遲到了,我的方法類似於@Mad Physicist。 這里的關鍵是要有一個查找表(矩陣)。 訣竅是始終將共享者放在首位,以便查找成功:

def share_share(agent1, agent2):
    print(f"Both share: {agent1} and {agent2}")
    
def steal_steal(agent1, agent2):
    print(f"Both steal: {agent1} and {agent2}")

    
def share_steal(sharer, stealer):
    print(f"{sharer=} and {stealer=}")
    

def interact(agent1, agent2):
    matrix = {
        ("AlwaysShare", "AlwaysShare"): share_share,
        ("AlwaysShare", "AlwaysSteal"): share_steal,
        ("AlwaysSteal", "AlwaysSteal"): steal_steal,
    }
    if agent2.type == "AlwaysShare":
        agent1, agent2 = agent2, agent1
    func = matrix[agent1.type, agent2.type]
    func(agent1, agent2)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM