【问题标题】:Making sentence/word plural based on value根据值使句子/单词复数
【发布时间】:2018-12-03 08:11:58
【问题描述】:

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

这就是我现在的做法

ret = f'Done! {deleted} entr{"y was" if deleted == 1 else "ies were"} removed.'

我知道这行得通,但是当我去阅读它时,它就坐不住了。我考虑过制作一个函数或使用 dict-switch(我有点喜欢),但也许有人知道更好的方法。

我尝试过的解决方案:

使用字典

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

使用函数

def plural(num: int):
    return 'y was' if num == 1 else 'ies were'

使用布尔运算符

ret = f'Done! {deleted} entr{deleted != 1 and "ies were" or "y was"} removed.'

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

【问题讨论】:

  • 您的解决方案看起来不错:自然语言通常不能很好地处理非常结构化的字符串,但有很多例外。
  • 布尔索引将是另一种选择["ies were", "y was"][deleted == 1]
  • 在你的函数变体中可能允许单数和复数形式(默认):def plural(num: int, single='': str, mult='s': str):。这使它在其他地方更有用。哦,然后在该函数中将 if num == 0 更改为 if num == 1
  • deleted = 0这个案子你是怎么处理的?
  • deleted == 0.. 嗯,这又是另一个原因,哈哈

标签: python python-3.x localization internationalization


【解决方案1】:

也许在这个单一的例子中(如果我们谈论的是几个要被拒绝的字符串)那么这样的方法就足够了。

但在一般情况下,本地化 (L10N) 和国际化 (I12N) 最好使用合适的库来处理。

对于 python,我们有一个标准库 gettext 可以用于此目的。它实际上是GNU gettext 的python API,这是一个很好的开始选择。 有补充资源:

  1. Step-by-step guide 如何本地化你的 python 脚本。
  2. A more in-depth introduction to GNU gettext 在 python 的上下文中。
  3. 或者 another one 如果以前不适合您。
  4. 最后,涉及更多但更全面的python internationalization guide

简而言之,L10N 和 I12N 的含义远不止复数...

【讨论】:

    【解决方案2】:

    虽然我发现 @sophros answer 知识渊博且内容丰富,但我认为这超出了我的需要。我决定编写自己的自定义类,因为我需要一些便宜又简单的东西,而且我可以重复使用不同的单词/句子。如果您喜欢,请随意使用!

    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}"
    

    测试它是否有效

    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
    

    负值

    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
    

    其他用例

    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
    

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

    要么在问题中使用我的一个示例,要么在我的问题中使用类似的方法,但这是 cmets 中建议的 @Ev. Kounis@9769953 的调整版本 (希望你们不要介意我把你的建议放在答案中)

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

    【讨论】:

      猜你喜欢
      • 2015-03-19
      • 2021-01-15
      • 2022-06-10
      • 1970-01-01
      • 2016-08-23
      • 1970-01-01
      • 1970-01-01
      • 2018-12-26
      • 1970-01-01
      相关资源
      最近更新 更多