Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
418 views
in Technique[技术] by (71.8m points)

python - Plural String Formatting

Given a dictionary of ints, I'm trying to format a string with each number, and a pluralization of the item.

Sample input dict:

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

Sample output str:

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

It needs to work with an arbitrary format string.

The best solution I've come up with is a PluralItem class to store two attributes, n (the original value), and s (the string 's' if plural, empty string '' if not). Subclassed for different pluralization methods

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'

Then make a new dict through comprehension and a classes mapping:

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

Lastly, the format string, and implementation:

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))

Outputs the following:

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

For such an undoubtedly common need, I'm hesitant to throw in the towel with such a convoluted solution.

Is there a way to format a string like this using the built-in format method, and minimal additional code? Pseudocode might be something like:

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

where parentheses return the contents if value is plural, or if contents has comma, means plural/singular

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Check out the inflect package. It will pluralize things, as well as do a whole host of other linguistic trickery. There are too many situations to special-case these yourself!

From the docs at the link above:

import inflect
p = inflect.engine()

# UNCONDITIONALLY FORM THE PLURAL
print("The plural of ", word, " is ", p.plural(word))

# CONDITIONALLY FORM THE PLURAL
print("I saw", cat_count, p.plural("cat",cat_count))

For your specific example:

{print(str(count) + " " + p.pluralize(string, count)) for string, count in data.items() }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...