str.format() 报错 KeyError

95
下面的代码会引发 KeyError 异常:
addr_list_formatted = []
addr_list_idx = 0

for addr in addr_list: # addr_list is a list
    addr_list_idx = addr_list_idx + 1
    addr_list_formatted.append("""
        "{0}"
        {
        "gamedir"  "str"
        "address"  "{1}"
        }
    """.format(addr_list_idx, addr))

为什么?

我正在使用Python 3.1。


1
你可以使用列表推导式来完成相同的任务(使用 enumerate 来获取索引)。 - SwiftsNamesake
参见(重复)https://dev59.com/KVsV5IYBdhLWcg3w-i0C - dreftymac
2个回答

169

问题在于你使用的 {} 字符并未指定格式化的键,你需要将它们加倍,因此将你的代码更改为:

addr_list_formatted.append("""
    "{0}"
    {{
    "gamedir"  "str"
    "address"  "{1}"
    }}
""".format(addr_list_idx, addr))

13
如果有人想在Python中使用JSON,该怎么办? - fijiaaron
5
@fijiaaron,在答案中的双重大括号{}只是告诉format方法这里没有要格式化的键(因此它们在格式化的字符串中被转义,这样构建JSON就不会有问题)。另外,还有其他高效的操作字符串的方法,例如join方法:"".join(['{"', var_name, '":', value, '}']) - mgc
1
我差点失去理智,直到找出问题所在。 - Dmitry Kankalovich
4
“@DmitryKankalovich,你已经失去理智了。Stack Overflow以及这里的每个人,只是你想象中的产物。(这至少是我一直对自己说的):)” - Lasse V. Karlsen

2

使用 str.format() 格式化 JSON 字符串并不理想,因为您需要转义花括号,正如接受的答案所指出的那样。

虽然这种方法可能适用于小型 JSON 模板,但如果有许多需要转义的花括号,模板将难以阅读。

一个更好的选择是 string.Template

from string import Template

addr_list = ["address 1, country 1", "address 2, country 2"]

addr_list_formatted = []
addr_list_idx = 0

template = Template("""
"${index}"
{
"gamedir"  "str"
"address"  "${address}"
}
""")

for addr in addr_list:
    addr_list_idx = addr_list_idx + 1
    formatted = template.substitute(index=addr_list_idx, address=addr)
    addr_list_formatted.append(formatted)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接