小编典典

多个字符串格式

python

给定ints的字典,我试图用每个数字格式化字符串,并对该项目进行复数处理。

样本输入dict

data = {'tree': 1, 'bush': 2, 'flower': 3, 'cactus': 0}

样本输出str

'My garden has 1 tree, 2 bushes, 3 flowers, and 0 cacti'

它需要使用任意格式的字符串。

我想出的最好的解决方案是一个PluralItem用于存储两个属性的类,n(原始值)和s's'如果是复数''则为字符串,如果不是则为空字符串)。为不同的多元方法分类

class PluralItem(object):
    def __init__(self, num):
        self.n = num
        self._get_s()
    def _get_s(self):
        self.s = '' if self.n == 1 else 's'

class PluralES(PluralItem):
    def _get_s(self):
        self.s = 's' if self.n == 1 else 'es'

class PluralI(PluralItem):
    def _get_s(self):
        self.s = 'us' if self.n == 1 else 'i'

然后dict通过理解和classes映射制作一个新的:

classes = {'bush': PluralES, 'cactus': PluralI, None: PluralItem}
plural_data = {key: classes.get(key, classes[None])(value) for key, value in data.items()}

最后,格式字符串和实现:

formatter = 'My garden has {tree.n} tree{tree.s}, {bush.n} bush{bush.s}, {flower.n} flower{flower.s}, and {cactus.n} cact{cactus.s}'
print(formatter.format(**plural_data))

输出以下内容:

My garden has 1 tree, 2 bushes, 3 flowers, and 0 cacti

对于如此毫无疑问的普遍需求,我犹豫不决地使用如此复杂的解决方案。

有没有一种方法可以使用内置方法来格式化这样的字符串format,并且只需最少的附加代码?伪代码可能类似于:

"{tree} tree{tree(s)}, {bush} bush{bush(es)}, {flower} flower{flower(s)}, {cactus} cact{cactus(i,us)}".format(data)

如果值是复数,或者如果内容带有逗号,则括号返回内容,表示复数/单数


阅读 223

收藏
2020-12-20

共1个答案

小编典典

使用自定义格式化程序

import string

class PluralFormatter(string.Formatter):
    def get_value(self, key, args, kwargs):
        if isinstance(key, int):
            return args[key]
        if key in kwargs:
            return kwargs[key]
        if '(' in key and key.endswith(')'):
            key, rest = key.split('(', 1)
            value = kwargs[key]
            suffix = rest.rstrip(')').split(',')
            if len(suffix) == 1:
                suffix.insert(0, '')
            return suffix[0] if value <= 1 else suffix[1]
        else:
            raise KeyError(key)

data = {'tree': 1, 'bush': 2, 'flower': 3, 'cactus': 0}
formatter = PluralFormatter()
fmt = "{tree} tree{tree(s)}, {bush} bush{bush(es)}, {flower} flower{flower(s)}, {cactus} cact{cactus(i,us)}"
print(formatter.format(fmt, **data))

输出:

1 tree, 2 bushes, 3 flowers, 0 cacti

更新

如果您使用的是Python
3.2+(str.format_map已添加),则可以使用使用自定义dict的OP的想法(请参阅注释)。

class PluralDict(dict):
    def __missing__(self, key):
        if '(' in key and key.endswith(')'):
            key, rest = key.split('(', 1)
            value = super().__getitem__(key)
            suffix = rest.rstrip(')').split(',')
            if len(suffix) == 1:
                suffix.insert(0, '')
            return suffix[0] if value <= 1 else suffix[1]
        raise KeyError(key)

data = PluralDict({'tree': 1, 'bush': 2, 'flower': 3, 'cactus': 0})
fmt = "{tree} tree{tree(s)}, {bush} bush{bush(es)}, {flower} flower{flower(s)}, {cactus} cact{cactus(i,us)}"
print(fmt.format_map(data))

输出:同上。

2020-12-20