python - 生成器可以在 python 中与 string.format 一起使用吗?

标签 python string format generator

"{}, {}, {}".format(*(1,2,3,4,5))

打印:

'1, 2, 3'

只要 format 中的 {} 的数量不超过元组的长度,它就可以工作。我想让它适用于任意长度的元组,如果长度不足,则用 - 填充它。为了避免对 {} 的数量做出假设,我想使用生成器。这是我的想法:

def tup(*args):
    for s in itertools.chain(args, itertools.repeat('-')):
        yield s

print "{}, {}, {}".format(*tup(1,2))

预期:

'1, 2, -'

但它永远不会回来。你能让它与发电机一起工作吗?有没有更好的方法?

最佳答案

如果您考虑一下,除了变量参数解包是一次解包之外,还有一个事实是 format 不一定按顺序获取其参数,如 ' {2} {1} {0}'

如果 format 只是采用一个序列而不需要单独的参数,您可以通过构建一个做正确事情的序列来解决这个问题。这是一个简单的例子:

class DefaultList(list):
    def __getitem__(self, idx):
        try:
            return super(DefaultList, self).__getitem__(idx)
        except IndexError:
            return '-'

当然,您的真实版本会包装任意可迭代对象,而不是 list 的子类,并且可能必须使用 tee 或内部缓存并引入新值按照要求,只有在你结束时才默认。 (您可能想在 ActiveState 上搜索“惰性列表”或“惰性序列”食谱,因为它们中有一些是这样做的。)但这足以说明示例。

现在,这对我们有什么帮助?它没有; *lst on a DefaultList 将尝试从事物中创建一个元组,为我们提供与我们已经拥有的参数数量完全相同的参数。但是,如果您有一个版本的 format 可以取而代之的是一系列 args 呢?然后你可以传递你的 DefaultList 就可以了。

你确实有:Formatter.vformat .

>>> string.Formatter().vformat('{0} {1} {2}', DefaultList([0, 1]), {})
'0 1 -'

但是,还有一种更简单的方法,一旦您显式使用 Formatter 而不是通过 str 方法隐式使用。您可以覆盖它的 get_value 方法和/或其 check_unused_args:

class DefaultFormatter(string.Formatter):
    def __init__(self, default):
        self.default = default

    # Allow excess arguments
    def check_unused_args(self, used_args, args, kwargs):
        pass

    # Fill in missing arguments
    def get_value(self, key, args, kwargs):
        try:
            return super(DefaultFormatter, self).get_value(key, args, kwargs)
        except IndexError:
            return '-'

f = DefaultFormatter('-')

print(f.vformat('{0} {2}', [0], {}))
print(f.vformat('{0} {2}', [0, 1, 2, 3], {}))

当然,您仍然需要将迭代器包装在提供 Sequence 协议(protocol)的东西中。


当我们这样做时,如果该语言具有“可迭代解包”协议(protocol),则可以更直接地解决您的问题。参见 here对于提出这样的事情的 python-ideas 线程,以及该想法存在的所有问题。 (另请注意,format 函数会使这更棘手,因为它必须直接使用解包协议(protocol),而不是依赖解释器神奇地完成它。但是,假设它这样做了,那么你d 只需要为处理 __unpack__ 的任何可迭代对象编写一个非常简单且通用的包装器。)

关于python - 生成器可以在 python 中与 string.format 一起使用吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18472436/

相关文章:

python - 从 xgboost 中提取权重和树结构 - plot trees

python - 中间层使tensorflow优化器停止工作

python - 从 Python 登录服务器和 MySQL

Javascript:如何检索 *string* 数字的小数位数?

python 水獭文档

c - 在 sscanf 中指定可变字段宽度

python - 删除 Python 中变量和字符串之间的空格

java - 有没有办法使用单个日期格式字符串来解析两种类型的日期?

java - 显示标签格式标签货币

r - 将十进制日转换为 HH :MM