根据值使句子/单词复数

Jab*_*Jab 5 python localization internationalization python-3.x

我想知道是否有一种首选的或至少更具可读性/漂亮/pythonic 的方式来根据放入其中的数据使句子复数。

这就是我现在的做法

ret = f'Done! {deleted} entr{"y was" if deleted == 1 else "ies were"} removed.'
Run Code Online (Sandbox Code Playgroud)

我知道这行得通,但是当我去阅读它时,它就是不舒服。我想过创建一个函数或使用 dict-switch(这是我有点喜欢的东西),但也许有人知道更好的方法。

我尝试过的解决方案:

使用字典

plural = {1:'y was'}
ret = f'Done! {deleted} entr{plural.get(deleted, "ies were")} removed.'
Run Code Online (Sandbox Code Playgroud)

使用函数

def plural(num: int):
    return 'y was' if num == 1 else 'ies were'
Run Code Online (Sandbox Code Playgroud)

使用布尔运算符

ret = f'Done! {deleted} entr{deleted != 1 and "ies were" or "y was"} removed.'
Run Code Online (Sandbox Code Playgroud)

这些确实是我现在能想到的唯一有意义的其他方式,也是我想要这样做的原因是因为我有多个地方需要将单词设为复数。问题是,我可能想在某些地方使用不同的措辞,并希望避免重复自己将单词设为复数以供人类阅读的格式。

Jab*_*Jab 2

虽然我发现@sophros 的回答非常知识渊博且信息丰富,但我认为这超出了我的需要。我决定编写自己的自定义类,因为我需要一些便宜且简单的东西,并且我可以将其重用于不同的单词/句子。喜欢的话就自己用吧!

class Plural:
    __slots__ = 'word', 'value', 'singular', 'plural', 'zero', 'ignore_negatives'

    def __init__(self, value: int, word: str = "", **kwargs):
        """
        Parameters
        ----------
        value : int
            The determining value
        word : str, optional
            The word to make plural. (defaults to "")
        singular : str, optional
            Appended to `word` if `value` == 1. (defaults to '')
        plural : str, optional
            Appended to `word` if `value` > 1. (defaults to 's')
        zero : str, optional
            Replaces `value` if `value` == 0. (defaults to 0)
        ignore_negatives : bool, optional
            This will raise ValueError if `value` is negative. (defaults to False)
            Set to True if you don't care about negative values.
        """

        self.value, self.word = value, word
        self.singular = kwargs.pop('singular', '')
        self.plural = kwargs.pop('plural', 's')
        self.zero = kwargs.pop('zero', 0)
        self.ignore_negatives = kwargs.pop('ignore_negatives', False)

    def __str__(self):
        v = self.value
        pluralizer = self.plural if abs(v) > 1 else self.singular

        if v < 0 and not self.ignore_negatives:
            raise ValueError

        return f"{v or self.zero} {self.word}{pluralizer}"
Run Code Online (Sandbox Code Playgroud)

测试它是否有效

print(Plural(-2, singular="entry", plural="entries", ignore_negatives = True))
#-2 entries
print(Plural(-1, singular="entry", plural="entries", ignore_negatives = True))
#-1 entry
print(Plural(0, singular="entry", plural="entries"))
#0 entries
print(Plural(1, singular="entry", plural="entries"))
#1 entry
print(Plural(2, singular="entry", plural="entries"))
#2 entries
Run Code Online (Sandbox Code Playgroud)

具有负值

print(Plural(-1, singular="entry", plural="entries"))
#Traceback (most recent call last):                                                                                            
#File "/home/main.py", line 53, in <module>                                                                                  
#    print(Plural(-1, singular="entry", plural="entries"))                                                                     
#  File "/home/main.py", line 43, in __str__                                                                                   
#    raise ValueError                                                                                                          
#ValueError
Run Code Online (Sandbox Code Playgroud)

其他用例

print(Plural(1, "entr", singular="y", plural="ies"))
#1 entry
print(Plural(2, "entr", singular="y", plural="ies"))
#2 entries
print(Plural(0, "value", zero="No"))
#No value
print(Plural(1, "value"))
#1 Value
print(Plural(2, "value"))
#2 Values
Run Code Online (Sandbox Code Playgroud)

如果你只是想要一个快速而肮脏的修复

要么使用我在问题中的示例之一,要么创建像我的问题中那样的方法,但这里有一个经过调整的版本,如@Ev。Kounis@9769953在评论中建议(希望你们不介意我在答案中提出您的建议)

def plural(num: int, word: str = "", single: str = "", mult: str = 's'):
    return f"{num} {(plural, singular)[abs(num) == 1]}"
Run Code Online (Sandbox Code Playgroud)