首页 > 解决方案 > 在此示例中,编写自定义循环以避免 str.format() 键错误的最佳方法是什么?

问题描述

我想输出如下所示的内容(每行 20 个项目,需要两个变量,一个用于索引 i,另一个用于书名 bookname,在本例中"Psalm"):

\hyperlink{Psalm1}{1} & \hyperlink{Psalm2}{2} & \hyperlink{Psalm3}{3}  ...

使用 Python(我的循环的简化,但足以显示关键错误)我尝试:

        for indx in range(1, 150, 20):
            line = r""" \\hline
\\hyperlink{{{bn}{i}}}{{{i}}}  & \\hyperlink{{{bn}{i+1}}}{{{i+1}}} & \\hyperlink{{{bn}{i+2}}}{{{i+2}}} ... 
""".format( i=indx, bn = bookname)

重新编码以避免i+1关键错误的最佳方法是什么?

标签: pythonloopskeyerror

解决方案


\hyperlink{Psalm1}{1}以下是使用不同方法生成字符串 ( ) 的示例:

i = 1
# string concatenation
formatted = r"\hyperlink{Psalm" + str(i) + "}{" + str(i) + "}"
# old-style formatting
formatted = r"\hyperlink{Psalm%d}{%d}" % (i, i))
# str.format
formatted = r"\hyperlink{{Psalm{0}}}{{{0}}}".format(i)
# f-string
formatted = rf"\hyperlink{{Psalm{i}}}{{{i}}}"

对于这种特殊情况,我发现旧式格式更“干净”,因为它不需要双花括号。

要在每行中打印 20 个字符串,您可以将生成器传递给str.join().

完整代码:

stop = 150
step = 20
for i in range(1, stop + 1, step):
    print(
        " & ".join(
            r"\hyperlink{Psalm%d}{%d}" % (n, n)
            for n in range(i, min(i + step, stop + 1))
        )
    )

或者您也可以使用“单线”:

stop = 150
step = 20
print(
    "\n".join(  # use " &\n".join(...) if you need trailing '&'
        " & ".join(
            r"\hyperlink{Psalm%d}{%d}" % (n, n)
            for n in range(i, min(i + step, stop + 1))
        )
        for i in range(1, stop + 1, step)
    )
)

推荐阅读