Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python:如何向键和dicts添加值_Python_Dictionary - Fatal编程技术网

Python:如何向键和dicts添加值

Python:如何向键和dicts添加值,python,dictionary,Python,Dictionary,我想有一个系统,分配不同的命令到不同的类别 这就是我们获取命令的方式: commands = [] for k, v in config['commands'].items(): commands.append(config['commands'][k]['command']) 有一个.yaml文件,其中每个命令都有不同的属性。一个命令和一个类别: command_one: category: "Information" command: "

我想有一个系统,分配不同的命令到不同的类别

这就是我们获取命令的方式:

commands = []
for k, v in config['commands'].items():
    commands.append(config['commands'][k]['command'])
有一个.yaml文件,其中每个命令都有不同的属性。一个命令和一个类别:

command_one:
    category: "Information"
    command: "info"
command_two:
    category: "Owneronly"
    command: "ban"
command_two:
    category: "Owneronly"
    command: "kick"
现在,我想在如下所示的集合中根据命令的类别对命令进行排序:

sortedCommands = {"Owneronly": ["ban", "kick"], "Information": ["info"]}
for k, v in config['commands'].items():
        commands.append(config['commands'][k]['category'])
编辑:您可以通过以下命令获取类别:

sortedCommands = {"Owneronly": ["ban", "kick"], "Information": ["info"]}
for k, v in config['commands'].items():
        commands.append(config['commands'][k]['category'])

像这样的方法应该会奏效:

from collections import defaultdict
sortedCommands = defaultdict(list)
for cfg in config['commands'].values():
    sortedCommands[cfg['category']].append(cfg['command'])

我个人不会在这里使用“排序”这个词,因为这里没有排序。这个操作只是重塑数据-我更喜欢像
commands\u by\u category
这样的名称。当然,您可以随意使用任何您想要的名称。

这是一种有点冗长(为了清楚起见)的方法:

commands_by_category = {}  # Initialize a dictionary 
for command in config['commands'].items():  # for each block
    category = command.get('category')  # unpack categoy
    cmd = command.get('cmd')  # unpack command
    cmds = commands_by_category.get(category, [])  # Get the current list, or a default empty list
    cmds.append(cmd)  # Append to list. 
    commands_by_category[category] = cmds  # Reassign back to the dict
注意:on lists在适当的位置工作,因此您必须拉出当前列表,追加并重新分配它

另一个更简洁的选项是按行为分组:

from itertools import groupby
from typing import Callable, Iterable

def group_by(iterable: Iterable, key: Callable) -> dict:
    return {r[0]: list(r[1]) for r in groupby(sorted(iterable, key=key), key)}

group_by(config['commands'].items(), lambda x: x.get("category"))
这需要一点时间来解包,但它的作用如下:

  • 使用和决定排序顺序的函数对iterable进行排序
  • 这里提供的函数是获取类别值的
    lambda
    。这是自然的字母数字排序
  • 然后使用相同的“键”功能进行分组
  • 排序和分组后,对于结果iterable中的每个项,将类别指定为键,将结果列表指定为新字典中的值
这里有一个小问题,它返回每个原始项目的完整dict,因此我们必须清理一些信息:

sorted_commands = group_by(config['commands'].items(), lambda x: x.get("category"))
commands_by_category = {k: [i.get('command') for i in v] for k, v in sorted_commands.items()}
所有这些工作都是针对每个类别项,使用列表理解,获取字典列表,只保留命令名

行动中的完整示例:

from itertools import groupby
from typing import Callable, Iterable

def group_by(iterable: Iterable, key: Callable) -> dict:
    return {r[0]: list(r[1]) for r in groupby(sorted(iterable, key=key), key)}

ls = [{"category": "Information", "command": "info"},
      {"category": "Owneronly", "command": "ban"},
      {"category": "Owneronly", "command": "kick"},
]

expected = {
    "Information": ["info"],
    "Owneronly": ["ban", "kick"],
}

sorted_commands = group_by(ls, lambda x: x.get("category"))
commands_by_category = {k: [i.get('command') for i in v] for k, v in sorted_commands.items()}

commands_by_category == expected  # True
这种方法虽然更密集,但功能更强大,并且利用了Python核心库。因此,我敢打赌它会更快