在python中,有哪些方法可以将两个列表以类似dict的格式链接在一起?

ebdffaop  于 2023-06-25  发布在  Python
关注(0)|答案(2)|浏览(131)

我正在开发一个不和谐的机器人类似于电子鸡接受许多命令。为了减少空间使用并使添加新命令更容易,我采用了双字典方法。第一个字典“COMMANDS”存储每个命令的所有接受的提示,而第二个字典“RESPONSES”将每个命令链接到其相应的响应。
下面是这两个字典的一个例子:

COMMANDS = {
    "wakeup": ["!goodmorning", "!wakeup", "!morning", "!wake"],
    "spit": ["!spit", "!ptoeey"],
    "punch": ["!punch"],
    "slap": ["!slap"],
    "kiss": ["!kiss"],
    "dance": ["!dance", "!play", "!jump", "!yippee", "!happy"],
    "pet": ["!pet", "!scritch"],
    "sniff": ["!sniff", "!jeffthekiller"],
    "sleep": ["!goodnight", "!sleep", "!night"],
    "bestfoods": ["!bestfoods", "!favorites", "!lovedfoods", "!yummys", "!yummies"],
    "goodfoods": ["!goodfoods", "!likes", "!goods", "!likedfoods"],
    "badfoods": ["!badfoods", "!bads", "!hates", "!hatedfoods"],
    "poisonfoods": ["!poisonousfoods", "!poison", "!poisons", "!dangerfoods", "!poisonfoods"],
    "eat": ["!eat"],
    "drink": ["!drink", "!slurp"],
    "status": ["!status"],
    "resurrect": ["!resurrect", "!live", "!rise", "!revive"]
}

self.RESPONSES = {
    "wakeup": self.wakeup,
    "spit": ["💦💦💦"],
    "punch": ["👊💥💥"],
    "slap": ["🫲💥💥"],
    "kiss": ["media/kiss.gif"],
    "dance": ["media/dance.gif"],
    "pet": ["media/normal_pet.gif", "media/fast_pet.gif", "media/slow_pet.gif", "media/squishy_pet.gif"],
    "sniff": ["media/sniff.gif"],
    "dead": ["media/dead.gif", "media/dead2.gif", "media/dead3.gif", "media/dead4.gif"],
    "sleep": self.sleep,
    "status": self.get_status_embed,
    "bestfoods": ("I love love love theese! " + "".join(self.stats["known_best_foods"])) if len(self.stats["known_best_foods"]) else "I don lolove anyfing........",
    "goodfoods": ("I like theese! " + "".join(self.stats["known_good_foods"])) if len(self.stats["known_good_foods"]) else "I don likke anyfing........",
    "badfoods": ("Thees arr GROSS!!! " + "".join(self.stats["known_bad_foods"])) if len(self.stats["known_bad_foods"]) else "I like everyfing!! Nuffins yuckyee",
    "poisonfoods": ("Thees HURTTT!!!!!! " + "".join(self.stats["known_poisonous_foods"])) if len(self.stats["known_poisonous_foods"]) else "Ai'm Invincble, nuffin hurts me!!",
    "resurrect": self.resurrect,
    "eat": self.eat,
}

为了获得响应,我分别使用命令和响应连接了两个字典。下面是实现:

for k, v in COMMANDS.items():
    if command[0] in v and k in self.RESPONSES:
        # If it's a list of responses, choose a random response
        if type(self.RESPONSES[k]) is list:
            responses.append(random.choice(self.RESPONSES[k]))
        else:
            # Else, it's a function reference. Process it
            response, action = self.RESPONSES[k](command)
            responses.extend(response) if type(response) is list else responses.append(response)
            actions.extend(action) if type(action) is list else actions.append(action)

我更喜欢这种方式,因为它将数据(命令和响应)从代码中分离出来,这意味着我需要编写更少的总体内容。然而,这两个字典变得混乱,使得它非常容易出错,因为我需要确保两个字典之间的键匹配。
有没有什么方法可以直接链接两个列表,而没有“命令”在中间?如果这是不可能的,你有什么建议,以其他解决这个问题的方法吗?

vwkv1x7d

vwkv1x7d1#

我的建议是使用一个嵌套的字典来存储特定命令的别名和响应。这避免了必须检查命令在两个不同的字典中是否相同。然后,使用列表解析生成命令字典的别名:

bot_io = {
    "wakeup": {
        "alias": ["!goodmorning", "!wakeup", "!morning", "!wake"],
        "response": [self.wakeup],
    },
    "spit": {"alias": ["!spit", "!ptoeey"], "response": ["💦💦💦"]},
}

alias_to_command = {alias: command for command in bot_io for alias in bot_io[command]['alias']}
jdgnovmf

jdgnovmf2#

如果你要线性搜索,没有必要使用字典,使用列表。您可以使它成为包含命令和响应的元组或字典的列表。

commands = [
    {"commands": ["!goodmorning", "!wakeup", "!morning", "!wake"],
     "response": self.wakeup},
    {"commands": ["!spit", "!ptoeey"],
     "response": ["💦💦💦"]},
    ...
]

for i in commands:
    if command[0] in i['commands']:
        if isinstance(i['response'], list):
            responses.append(random.choice(i['response']))
        else:
            response, action = i['response'](command)
            responses.extend(response) if type(response) is list else responses.append(response)
            actions.extend(action) if type(action) is list else actions.append(action)
        break

相关问题