我有一个复杂的字典,使一个有组织的输出,但需要把它传递给另一个modu

2024-05-17 18:32:46 发布

您现在位置:Python中文网/ 问答频道 /正文

首先,我是Python的新手,编码对我来说很难开始。你知道吗

所以我有一个字典格式(由于API)如下。你知道吗

可以添加键和值,所以我想我需要某种循环。你知道吗

agilityskills = {'Archery': {'Archery': 4, 'Crossbow': 6, 'Bow': 6}, 'Pistols': {'Pistols': 6, 'Semi-Automatics': 8, 'Holdouts': 8}, 'Gymnastics': {'Gymnastics': 6, 'Balancing': 8}, 'Blades': {'Blades': 5}}

我希望它有一个输出

Archery(Bow)(Crossbow) >--------------------------------> 4(6)
Pistols(Semi-Automatics)(Holdouts) >--------------------> 6(8)  
Gymnastics(Balancing) >---------------------------------> 6(8) 
Blades >------------------------------------------------> 5

我不想打印这个,但是把它传递给另一个模块,所以可以使用一个函数或变量作为结果?你知道吗


Tags: api编码字典格式新手semibalancingholdouts
1条回答
网友
1楼 · 发布于 2024-05-17 18:32:46

OP已经澄清了确切的格式可以等待,所以让我们从“业务逻辑”开始,使用pprint只是为了更可读地显示第一阶段的结果:

import pprint

agilityskills = {
    'Archery': {'Archery': 4, 'Crossbow': 6, 'Bow': 6},
    'Pistols': {'Pistols': 6, 'Semi-Automatics': 8, 'Holdouts': 8},
    'Gymnastics': {'Gymnastics': 6, 'Balancing': 8},
    'Blades': {'Blades': 5}
}

def refactor(ask):
    result = []
    for s in ask:
        ss = [s1 for s1 in ask[s] if s1 != s]
        skills = [s] + ss
        scores = [ask[s][s1] for s1 in skills]
        result.append([skills, scores])
    return result

pprint.pprint(refactor(agilityskills))

结果显示:

[[['Archery', 'Crossbow', 'Bow'], [4, 6, 6]],
 [['Pistols', 'Holdouts', 'Semi-Automatics'], [6, 8, 8]],
 [['Gymnastics', 'Balancing'], [6, 8]],
 [['Blades'], [5]]]

它以所需的分组和相应的顺序给出技能名称和分数,但尚未格式化为每个子列表的单个字符串。请注意,子列表的顺序不能保证它在这里按所需“工作”,但这是随机的,因为通常dict无法保持顺序(我注意到,如果运行此代码,在Pistols子技能之间会发生一次“交换”,您可能会看到其他代码)。你知道吗

如果顺序很重要,则需要单独记录(collections.OrderedDict有时会有所帮助,但我看到在许多情况下,它也会让编码人员感到惊讶,所以让我们把转移到一个单独的未来问题,如果需要的话:-)。你知道吗

不管怎样,我们来看看格式。条目所需的输出字符串如下所示:

Archery(Bow)(Crossbow) >                > 4(6)

(困难的部分是只有正确数量的破折号,我将传递一个!-). 你知道吗

因此,根据上面的refactor得到的嵌套列表,我们可以很容易地进行大部分格式化…:

def withparens(ss):
    fss = [str(ss[0])]
    for s1 in ss[1:]:
        fss.append('({})'.format(s1))
    return ''.join(fss)

def formatit(rf, numdashes=6):
    result = []
    for skills, scores in rf:
        result.append('{} >{}> {}'.format(
            withparens(skills),
            '-' * numdashes,
            withparens(scores)))
    return result

result = formatit(refactor(agilityskills))

for line in result:
    print(line)

现在,这表明:

Archery(Crossbow)(Bow) >   > 4(6)(6)
Pistols(Holdouts)(Semi-Automatics) >   > 6(8)(8)
Gymnastics(Balancing) >   > 6(8)
Blades >   > 5

…这几乎是期望的结果,除了固定为6的破折号数(或任何其他单个任意值)显然会产生一个丑陋的结果。相反,对于formatit生成的每一行,破折号的数量应该是不同的,以便得到良好的对齐效果。但是这样做通常是很难的,我的划船:-). 你知道吗

尽管如此,我们仍然可以通过思考“到>线的起始长度”来做一点更好的事情,这似乎是OP的问题所关注的均衡。所以…:

def formatitbetter(rf):
    result = []
    for skills, scores in rf:
        fsk = withparens(skills)
        numdashes = 53 - len(fsk)
        result.append('{} >{}> {}'.format(
            fsk,
            '-' * numdashes,
            withparens(scores)))
    return result

result = formatitbetter(refactor(agilityskills))

for line in result:
    print(line)

现在,运行这个命令可以精确地显示OP要求的结果(如果我正确地计算了破折号的数量,否则,调整这个神奇常数53为口味:-)…:

Archery(Crossbow)(Bow) >               -> 4(6)(6)
Pistols(Holdouts)(Semi-Automatics) >         -> 6(8)(8)
Gymnastics(Balancing) >                > 6(8)
Blades >                       -> 5

当然,问题是,如果某个技能有很多名字很长的子技能,这就不会为破折号留下足够的空间;如果我们把行弄长一些,那么不管OP最初想做什么“漂亮的展示”,有些可能“太长”。正是在表达部分实现了普遍性,才使得表达问题,完全的普遍性,成为一个困难的问题!-)你知道吗

(现在大多数演示将使用非单间距的字体,这使得事情变得更加困难,因为文本字符串的“视觉”长度不仅仅是该文本中字符/字形的数量,而是取决于字体的度量。。。够让人头疼的了,尤其是像我这样的人,因为我是一个高度口头化、非视觉化、思想者!-)你知道吗

相关问题 更多 >