给定ints的字典,我试图用每个数字格式化字符串,并对该项目进行复数处理。
int
样本输入dict:
dict
data = {'tree': 1, 'bush': 2, 'flower': 3, 'cactus': 0}
样本输出str:
str
'My garden has 1 tree, 2 bushes, 3 flowers, and 0 cacti'
它需要使用任意格式的字符串。
我想出的最好的解决方案是一个PluralItem用于存储两个属性的类,n(原始值)和s('s'如果是复数''则为字符串,如果不是则为空字符串)。为不同的多元方法分类
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
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,并且只需最少的附加代码?伪代码可能类似于:
format
"{tree} tree{tree(s)}, {bush} bush{bush(es)}, {flower} flower{flower(s)}, {cactus} cact{cactus(i,us)}".format(data)
如果值是复数,或者如果内容带有逗号,则括号返回内容,表示复数/单数
使用自定义格式化程序:
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的想法(请参阅注释)。
str.format_map
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))
输出:同上。