我有一个复杂的字典来制作有组织的输出,但需要将它传递给另一个模块

I have a complex Dictionary to make a organized output but need to pass it to another module

首先,我是 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

我不想打印它,而是将它传递给另一个模块,所以可以将结果用作函数或变量吗?

OP 已经阐明确切的格式可以等待,所以让我们从 "business logic" 开始,使用 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]]]

它给出了所需分组和相应顺序中的技能名称和分数,但尚未格式化为每个子列表的单个字符串。请注意,无法保证子列表的顺序 - 它恰好是 "work" 此处所需的,但这是随机的,因为通常 dict 无法维持顺序(我确实注意到它发生了一个"swap" 之间 Pistols 子技能 -- 如果你 运行 这个代码你可能会看到其他人)。

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

不管怎样,先进行一些格式设置。条目所需的输出字符串如下:

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

(困难的部分是只有正确数量的破折号,我将传递 那个 一个!-)。

因此,根据上面 refactor 的结果嵌套列表,我们可以轻松地进行 大多数 格式化...:[=​​25=]

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 生成的每一行的破折号数量应该有所不同,以便生成良好的对齐方式。但是通常 这样做很难,我的赌注是:-)。

不过,我们可以做得更好 一点 -- 通过考虑 "length of the start of the line up to the >" 这似乎是 OP 的问题集中在均衡上的问题。所以...:[=​​25=]

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)

Now, 运行ning 这准确地显示了 OP 要求的结果(如果我已经正确计算破折号的数量,否则,调整那个魔术常数53 品尝:-)...:[=​​25=]

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

问题当然是,如果某些技能有很多长名称的子技能,这将不会为破折号留下足够的 space;如果我们让行更长一些可能是 "too long" 出于 OP 最初想到的任何目的 "pretty display" 。它在表示部分实现了通用性,这使得表示问题,在完全通用性方面,是一个困难的问题!-)

(如今大多数演示文稿都将使用非单色 spaced 的字体,这让事情变得更加困难,因为文本字符串的 "visual" 长度不仅仅是characters/glyphs 在该文本中,而是取决于字体的度量标准......足以让一些人头疼,特别是对于像我这样的人来说,因为我是一个高度口头的人, -视觉,思想家!-)