在此示例中编写自定义循环以避免 str.format() 键错误的最佳方法?

Best way to code custom loop to avoid str.format() key error in this example?

我想输出这样的东西(每行 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 键错误的最佳重新编码方法是什么?

尝试使用f字符串

for i in range(1, 150, 20):
  print(f"\hyperlinkPPsalm{i} & \hyperlinkPsalm{i+1} & \hyperlinkPsalm{i+2}")

这是使用不同方法生成字符串 (\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}}}"

对于这种特殊情况,我发现 old-style formatting 更“干净”,因为它不需要加倍大括号。

要在每行中打印 20 个字符串,您可以通过 generator which will produce formatted strings into 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)
    )
)