第二次传递.format()时发生Python KeyError

时间:2018-09-06 11:34:10

标签: python-3.x format

我正在使用.format()自动生成菜单。但是,随着用户运行更多测试以表明这些测试已经完成,我还需要对其进行格式化。

示例测试字典:

menuDict = {
    "1":
        {"testDataDict": "testDataDict1",
        "testName": "testName1",
        "testGroupName":"testGroupName1"},
    "2":
         {"testDataDict": "testDataDict2",
        "testName": "testName2",
        "testGroupName":"testGroupName2"
         },
    "3":
         {"testDataDict": "testDataDict3",
        "testName": "testName3",
        "testGroupName":"testGroupName3"
         },
     "4":
    {"testDataDict": "testDataDict4",
    "testName": "testName4",
    "testGroupName":"testGroupName3"
    }
    }

实际代码:

def menuAutoCreate(menuDict):
testGroupDict = {}
for testNum in menuDict.keys():
    try:
        testGroupDict[menuDict[testNum]["testGroupName"]].append(testNum)
    except:
        testGroupDict[menuDict[testNum]["testGroupName"]] = [testNum]
 #Groups the tests under the group names       

from natsort import natsorted as nt  
testGroupNamesList = nt(testGroupDict.keys(), key=lambda y: y.lower())
#Naturally sorts group names so they look orderly

textDump = " "
i = 0
while i < len(testGroupNamesList):
    howManyLinesEven = 0
    evenList = []
    howManyLinesOdd = 0
    oddList = []

    testGroupNameEven = testGroupNamesList[i]
    textDump += "|{:44}         |".format(testGroupNameEven)
    howManyLinesEven = len(testGroupDict[testGroupNameEven])

    evenList = nt(testGroupDict[testGroupNameEven], key=lambda y: y.lower())
    #If it's an even number, it puts the menu template on the left side of the screen


    if i != len(testGroupNamesList)-1:
        testGroupNameOdd = testGroupNamesList[i+1]
        textDump += "{:45}         |".format(testGroupNameOdd) + "\n"
        howManyLinesOdd = len(testGroupDict[testGroupNameOdd])   
        oddList = nt(testGroupDict[testGroupNameOdd], key=lambda y: y.lower())
    #If it's odd, on the right side.  

    if i == len(testGroupNamesList)-1:
        textDump += "{:45}         |".format("") + "\n"
        #Ensures everything is correctly whitespaced

    howManyLines = max(howManyLinesEven, howManyLinesOdd)
    #Checks how many lines there are, so if a group has less tests, it will have extra whitespaces

    for line in range(howManyLines):
        if line < howManyLinesEven:
            data = {"testNum": evenList[line], "testName": menuDict[evenList[line]]["testName"]}
            textDump += "|({d[testNum]}) {d[testName]:40}    {{doneTests[{d[testNum]!r}]:^8}} |".format(d=data)
        else:
            textDump += "|{:44}         |".format("")

        if line < howManyLinesOdd:
            data = {"testNum": oddList[line], "testName": menuDict[oddList[line]]["testName"]}
            textDump += "({d[testNum]}) {d[testName]:41}    {{doneTests[{d[testNum]!r}]:^8}} |".format(d=data) + "\n"
        else:
            textDump += "{:45}         |".format("") + "\n"
        #Automatically creates a menu

    i += 2

print(textDump)
print("\n")

此输出,如预期:

|testGroupName1                                       |testGroupName2                                        |
|(1) testName1                    {doneTests['1']:^8} |(2) testName2                     {doneTests['2']:^8} |
|testGroupName3                                       |                                                      |
|(3) testName3                    {doneTests['3']:^8} |                                                      |
|(4) testName4                    {doneTests['4']:^8} |                                                      |                                                     |

最后一步将在其他地方完成,但请在此处进行演示:

    doneTests = {}
for testNum in menuDict.keys():
    doneTests[testNum] = "(-)"        
print(doneTests)

#textDump.format(**doneTests)
#This doesn't work for some reason?

textDump.format(doneTests = doneTests)

#This step will be repeated as the user does more tests, as an indicator of 
 which tests are completed. 

预期输出为:

|testGroupName1                                       |testGroupName2                                        |
|(1) testName1                    (-)                 |(2) testName2                     (-) |
|testGroupName3                                       |                                                      |
|(3) testName3                    (-) |                                                      |
|(4) testName4                    (-) |                                                      |                                                     |

但是在这里它抛出:

KeyError: "'1'"

如果从以下位置删除!r,则

{{doneTests[{d[testNum]!r}]:^8}}

它抛出一个

KeyError: 1 

相反。

我尝试使用!s格式化。使用列表/元组。添加和卸下支架。此时没有想法...

1 个答案:

答案 0 :(得分:0)

只需尝试您的示例。

我使用函数sorted()代替了natsorted(),并添加了行

textDump = ''

在行

之前初始化textDump变量
i = 0

结果是我没有错误,并获得了预期的输出。

编辑

现在,我转载了您的错误。我从!r中删除了{{doneTests[{d[testNum]!r}]:^8}},并在doneTests变量

中使用了整数键
doneTests[int(testNum)] = "(-)"

解决问题。我想问题的根源是format()方法的工作原理。