从嵌套的dict中选择一个随机值,并在另一个嵌套的dict中更新它

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从嵌套的dict中选择一个随机值,并在另一个嵌套的dict中更新它相关的知识,希望对你有一定的参考价值。

我正在编写python中的RPG文本游戏,我正在尝试在每次启动时创建随机遇到系统。我有一个有多个遭遇的词典及其相应的类别和另一个嵌套的词典,其中包含有关游戏区域的信息。我可以创建一个随机选择并将其打印出来,但是如何在区域嵌套表中的每个“交互”中更新随机选择。我想从区域嵌套字典中的每个“交互”键的遇到表中获得一个新的随机值。

另外我只需要更新值,所以"interact" : "zombie"例如,类别只是加权随机选择,因为我希望它们是“随机的”,其中大部分都没有(“”)或敌人

虽然这是最新版本,因为我尝试了很多不同的方法,它们都失败了 - 下面的代码也出错了,我不知道如何解决这个问题。如果需要,我也可以发布所有其他尝试。

这是我失败的尝试:

import random

encounters = {
    "enemy" : {
        1 : "zombie",
        2 : "wolf",
        3 : "wraith"
    },

    "chest" : {
        1 : "chest",
        2 : "weapons_chest",
    },

    "npc"   : {
        1 : "villager",
    },

    "furniture" : {
        1 : "bed"
    },

    "nothing"   : {
        1 : ""
    }
}

area = {

    "spawner" : {

        "spawn" : {
            "name"      : "Spawn",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    },

    "alley" : {

        "alleyway_1"   : {
            "name"      : "Alleyway 1",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "spawn",
                2   : "alleyway_2",
                3   : "hall"
            }
        },

        "alleyway_2"   : {
            "name"      : "Alleyway 2",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    }
}

def random_encounters():
    print("random encounters")

    weights_a = [0.3, 0.1, 0.05, 0.05, 0.5]

    encounter_a = random.choices(encounters, weights_a)
    encounter_b = random.choice(list(encounter_a.values()))

    for q, w in area.items():
        for a, s in area[w].items():
            area[w][s]["interact"] = encounter_b

random_encounters()

编辑:

预期结果将是:

 area = {

    "spawner" : {

        "spawn" : {
            "name"      : "Spawn",
            "interact"  : "bed",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    },

    "alley" : {

        "alleyway_1"   : {
            "name"      : "Alleyway 1",
            "interact"  : "zombie",
            "solved"    : False,
            "connects"  : {
                1   : "spawn",
                2   : "alleyway_2",
                3   : "hall"
            }
        },

        "alleyway_2"   : {
            "name"      : "Alleyway 2",
            "interact"  : "chest",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    }
}

其中"interact" : "zombie"僵尸是random_encounters()的输出

答案

由于random.choicesrandom.choice仅适用于列表类型,因此您可以获取对象键列表并随机选择其中一个。选择的结果密钥将用于访问子字典项。还有一件事,当使用for key, values in dictionary.items()遍历字典时,第一个变量将是字典键,另一个变量将是与该键对应的值。我认为你混淆了两者的顺序所以我也为你解决了这个问题。

我还添加了import jsonprint(json.dumps(area, indent=2)),以便您可以验证它是您想要的。您可以在完成测试后将其删除。

编辑:为了设置不同区域的唯一遭遇,您将随机遭遇生成代码放在2 for循环内,以便每个区域都有自己的随机遭遇。此外,由于你想设置每个项目都有一定的概率发生,并且使用list(encounters.keys())会以随机顺序给出一个字典键的列表,我决定从使用list(encounters.keys())改为使用encounters_keys=["enemy", "chest", "npc", "furniture", "nothing"],其中encounters'键的顺序相同weights_a使每种类型的遭遇具有正确的概率。

import random
import json

encounters = {
    "enemy" : {
        1 : "zombie",
        2 : "wolf",
        3 : "wraith"
    },

    "chest" : {
        1 : "chest",
        2 : "weapons_chest",
    },

    "npc"   : {
        1 : "villager",
    },

    "furniture" : {
        1 : "bed"
    },

    "nothing"   : {
        1 : ""
    }
}

area = {

    "spawner" : {

        "spawn" : {
            "name"      : "Spawn",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    },

    "alley" : {

        "alleyway_1"   : {
            "name"      : "Alleyway 1",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "spawn",
                2   : "alleyway_2",
                3   : "hall"
            }
        },

        "alleyway_2"   : {
            "name"      : "Alleyway 2",
            "interact"  : "",
            "solved"    : False,
            "connects"  : {
                1   : "alleyway_1"
            }
        }
    }
}
def random_encounters():
    print("random encounters")
    encounters_keys = ["enemy", "chest", "npc", "furniture", "nothing"]
    weights_a = [0.3, 0.1, 0.05, 0.05, 0.5]

    for q, w in area.items():
        for a, s in area[q].items():
            encounter_a = random.choices(encounters_keys, weights_a)[0]
            encounter_b = random.choice(list(encounters[encounter_a].keys()))
            area[q][a]["interact"] = encounters[encounter_a][encounter_b]

    print(json.dumps(area, indent=2))

random_encounters()

以上是关于从嵌套的dict中选择一个随机值,并在另一个嵌套的dict中更新它的主要内容,如果未能解决你的问题,请参考以下文章

服务器与本地机器上dict键的随机顺序[重复]

将字典嵌套在另一个字典中,按 Pandas Dataframe 中的值分组

使用 LINQ 根据 C# 中的属性值搜索嵌套在另一个列表中的列表中的项目?

如何在 tcl 中使用 dict 附加嵌套 dict

检查嵌套字典值?

用映射字典的值替换嵌套字典中的占位符