关于第二次传递.format()的Python KeyError
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于第二次传递.format()的Python KeyError相关的知识,希望对你有一定的参考价值。
我正在使用.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) + "
"
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("") + "
"
#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) + "
"
else:
textDump += "{:45} |".format("") + "
"
#Automatically creates a menu
i += 2
print(textDump)
print("
")
正如预期的那样输出:
|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格式化。使用列表/元组。添加和删除括号。出于这个想法......
答案
试过你的例子。
我使用函数sorted()
而不是natsorted()
并添加了该行
textDump = ''
在行之前初始化textDump
变量
i = 0
结果我没有错误并得到了预期的输出。
编辑
现在我重现了你的错误。我从!r
中删除了{{doneTests[{d[testNum]!r}]:^8}}
并在doneTests
变量中使用了整数键
doneTests[int(testNum)] = "(-)"
解决问题。我想问题的根源是format()
方法的工作原理。
以上是关于关于第二次传递.format()的Python KeyError的主要内容,如果未能解决你的问题,请参考以下文章
关于Python的TypeError not all arguments converted during string formatting