代码之家  ›  专栏  ›  技术社区  ›  Asclepius

Python:列表中语法正确的可读字符串(用牛津逗号)

  •  -2
  • Asclepius  · 技术社区  · 5 年前

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

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

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

    2 回复  |  直到 5 年前
        1
  •  11
  •   Asclepius    4 年前

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

    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
  •  1
  •   Ajax1234    5 年前

    您也可以使用解包进行 清洁剂溶液:

    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
  •  0
  •   Giacomo Casoni    5 年前

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

    "{} 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)))])
    

    编辑
    我觉得这个很管用。我认为这个问题也比我想象的要复杂得多,用一条不难看的线就能解决。

        4
  •  0
  •   Christian Tiago Ferraz    5 年前

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

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