【问题标题】:How to format variable number of arguments?如何格式化可变数量的参数?
【发布时间】:2021-06-04 21:29:30
【问题描述】:

我有一个参数列表,我想将其应用于模板格式字符串列表。我的问题是每个模板字符串都可以采用可变数量的参数。我想避免每个字符串需要多少个参数的硬编码列表

counts = [1, 0, 2, 3, 1] # How to get rid of this counts list?
arguments = ["a", "b", "c", "d", "e", "f", "g"] 
templates = [
    "{} one",
    "none",
    "{} two {}",
    "{} {} three {}",
    "one2 {}",
]

start = 0
for i, template in enumerate(templates):
    count = counts[i] # a programmatic way to get the count for current template?
    print(template.format(*arguments[start : start + count]))
    start += count

输出:

一个

b 两个 c
d e 三f
一个2克

如何在不知道每种格式需要多少变量的情况下将字符串列表应用于格式模板列表?

【问题讨论】:

  • 您也可以考虑对字符串进行正则表达式,这可能是 Python 在后台所做的。

标签: python string format


【解决方案1】:

您可以使用在模板或参数中不太可能看到的字符连接所有模板,进行字符串插值,然后拆分结果。

templates = [
    "{} one",
    "none",
    "{} two {}",
    "{} {} three {}",
    "one2 {}",
    "and {{literal}} braces {{}}"
]
arguments = ["a", "b", "c", "d", "e", "f", "g"] 

joined_template = chr(1).join(templates)

formatted_string = joined_template.format(*arguments)

formatted_templates = formatted_string.split(chr(1))

formatted_templates 现在是:

['a one',
 'none',
 'b two c',
 'd e three f',
 'one2 g',
 'and {literal} braces {}']

【讨论】:

  • 这不包括用于加入模板的任何内容。
  • 如第一句所述。不过,您不太可能在现实生活中的字符串中看到诸如 chr(0)chr(1) 之类的控制字符,因此这是一个不错的折衷 IMO @pystr
  • 我实际上会说您的问题与您在单个字符串中看到的问题相同。您只是创建一个长字符串,然后应用您的参数。如果您确定参数和模板槽的总数是相等的,那可能很好 - 如果您尝试做除此之外的任何事情,那么它就会崩溃。也许这对这个用例来说很好,但我很难想到那个案例的应用不会提出其他更直接的解决方案。
  • 我想我希望 python 提供一些方法来获取计数。但这似乎是最好的选择。我同意您的 cmets 并感谢您的两个回答。谢谢。
  • 同意;但是,如果您需要模板或参数的某个子集,或者需要直觉如何排列其中一个或另一个的列表,则很难避免这样做。我也希望模板不要太长……但这些都是与他提出的问题不同的问题,而您在此处列出的问题空间的倒置是一个很好的工具!
【解决方案2】:

而不是硬编码你的计数,只需count 每个模板中有效大括号的数量。一个简单的方法是这样的:

>>> "{} {} three {}".count("{}")
3
>>> "none".count("{}")
0

所以你的程序看起来像这样:

arguments = ["a", "b", "c", "d", "e", "f", "g"] 
templates = [
    "{{}} one",
    "none",
    "{} two {}",
    "{} {} three {}",
    "one2 {}",
    "and {{literal}} braces {{}}"
]

start = 0
for template in templates:
    count = template.count("{}")
    print(template.format(*arguments[start : start + count]))
    start += count

在 REPL 中:

>>> arguments = ["a", "b", "c", "d", "e", "f", "g"]
>>> templates = [
...     "{} one",
...     "none",
...     "{} two {}",
...     "{} {} three {}",
...     "one2 {}",
...     "and {{literal}} braces {{}}"
... ]
>>>
>>> start = 0
>>> for template in templates:
...     count = template.count("{}")
...     print(template.format(*arguments[start : start + count]))
...     start += count
...
{} one
none
b two c
d e three f
one2 g
and {literal} braces {}

【讨论】:

  • 这似乎是一个不错的解决方案,但对于带有大括号的模板来说却失败了。 “{{}}文字{}”
  • 嗯...不过,您希望该模板输出什么? "{{}}".format("a") 返回{}
  • “{{}} text {}”的计数应该是 1 而不是 2,因为“{{}} text {}”.format() 接受 1 个参数而不是 2。“{ {}}" 应为 0。
  • 是的!说得通。当然,此解决方案不会涵盖这种情况,并且不会没有大量错误检查。在这种情况下,加入模板然后分发参数的答案可能是您想要的 - 除非这些计数不兼容。
  • 我接受了加入方案。感谢您的解决方案以及纳撒尼尔。!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-10-15
  • 2012-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多