【问题标题】:Grammatically correct human readable string from list (with Oxford comma)列表中语法正确的人类可读字符串(使用牛津逗号)
【发布时间】:2021-04-12 02:01:04
【问题描述】:

我想要一个语法正确的人类可读的列表字符串表示。例如,列表['A', 2, None, 'B,B', 'C,C,C'] 应该返回字符串A, 2, None, B,B, and C,C,C。这个人为的例子有点必要。请注意,Oxford comma 与此问题相关。

我尝试了', '.join(seq),但这并没有产生上述示例的预期结果。

注意先前存在的类似问题:

【问题讨论】:

    标签: python list human-readable


    【解决方案1】:

    此函数的工作原理是处理小列表与处理大列表不同。

    from typing import Any, List
    
    def readable_list(seq: List[Any]) -> str:
        """Return a grammatically correct human readable string (with an Oxford comma)."""
        # Ref: https://stackoverflow.com/a/53981846/
        seq = [str(s) for s in seq]
        if len(seq) < 3:
            return ' and '.join(seq)
        return ', '.join(seq[:-1]) + ', and ' + seq[-1]
    

    用法示例:

    readable_list([])
    ''
    
    readable_list(['A'])
    'A'
    
    readable_list(['A', 2])
    'A and 2'
    
    readable_list(['A', None, 'C'])
    'A, None, and C'
    
    readable_list(['A', 'B,B', 'C,C,C'])
    'A, B,B, and C,C,C'
    
    readable_list(['A', 'B', 'C', 'D'])
    'A, B, C, and D'
    

    【讨论】:

      【解决方案2】:

      您也可以使用解包来获得稍微更清洁的解决方案:

      def readable_list(_s):
        if len(_s) < 3:
          return ' and '.join(map(str, _s))
        *a, b = _s
        return f"{', '.join(map(str, a))}, and {b}"
      

      vals = [[], ['A'], ['A', 2], ['A', None, 'C'], ['A', 'B,B', 'C,C,C'], ['A', 'B', 'C', 'D']]
      print([readable_list(i) for i in vals])
      

      输出:

      ['', 'A', 'A and 2', 'A, None, and C', 'A, B,B, and C,C,C', 'A, B, C, and D']
      

      【讨论】:

        【解决方案3】:

        基于thread you linked to 的accepted answer,这里有一个单行语句,它接受一个可选参数来决定是否使用牛津逗号。

        from typing import List
        
        def list_items_in_english(l: List[str], oxford_comma: bool = True) -> str:
            """
            Produce a list of the items formatted as they would be in an English sentence.
            So one item returns just the item, passing two items returns "item1 and item2" and
            three returns "item1, item2, and item3" with an optional Oxford comma.
            """
            return ", ".join(l[:-2] + [((oxford_comma and len(l) != 2) * ',' + " and ").join(l[-2:])])
        

        【讨论】:

          【解决方案4】:

          我真的很固执,我真的很想找出一个单一的解决方案。

          "{} and {}".format(seq[0], seq[1]) if len(seq)==2 else ', '.join([str(x) if (y < len(seq)-1 or len(seq)<=1) else "and {}".format(str(x)) for x, y in zip(seq, range(len(seq)))])
          

          我认为这个可以解决问题。而且我认为这个问题也比我想象的用不难看的单线解决方案要复杂。

          【讨论】:

          • 嗯?你为什么这么说?我认为该命令做了我认为 OP 想做的事情
          • 对不起,我误会了,我收回了旗帜。一切都很好:)
          • @GiacomoCasoni 给定seq = [1, 2],返回值在语法上应该是'1 and 2',但这个答案返回'1, and 2',而不是正确的。
          • 这个答案应该被修复(同时保持其原创性)或被删除。最好是固定的。
          • 哦,我一定误解了什么是牛津逗号。让我看看能不能改一下
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2019-10-24
          • 1970-01-01
          • 2018-09-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多