如何使用逗号有效地连接列表并在最后一个元素之前添加"和"

das*_*chs 4 python list

我一直在经历Automatetheboringstuff,并遇到了一个名为逗号代码的挑战(第4章末).你必须编写一个函数,它接受一个列表并打印出一个字符串,用逗号连接元素并在最后一个元素之前添加"和".

请记住,我对python很新,或为此编程,它仍然是一个可管理的任务,但输出在插入"和"之前有一个逗号.所以我修改了代码来清理它.这是我的代码:

def comma_separator(someList):
    """The function comma_separator takes a list and joins it
       into a string with (", ") and adds " and " before the last value."""

    if type(someList) is list and bool(someList) is True:
        return ", ".join(someList[:-1]) + " and " + someList[-1]
    else:
        print("Pass a non-empty list as the argument.")
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法呢?有没有可以做到这一点的模块?

Mar*_*ers 13

你必须考虑到你只有一个元素的情况:

def comma_separator(sequence):
    if not sequence:
        return ''
    if len(sequence) == 1:
        return sequence[0]
    return '{} and {}'.format(', '.join(sequence[:-1]), sequence[-1])
Run Code Online (Sandbox Code Playgroud)

请注意,这bool(sequence) is True是一种非常精细的非空列表测试方法; 只需使用if sequence:就足够了,因为if语句已经查找了布尔真值.

可以说,使用序列以外的任何东西调用函数(可以索引并具有长度的东西)应该只会导致异常.您通常不会测试这些函数中的类型.如果你没有要测试一个类型,使用isinstance(sequence, list)至少允许子类.

传入一个空列表我也是一个错误.您可以将该异常转换为ValueError:

def comma_separator(sequence):
    if len(sequence) > 1:
        return '{} and {}'.format(', '.join(sequence[:-1]), sequence[-1])
    try:
        return sequence[0]
    except IndexError:
        raise ValueError('Must pass in at least one element')
Run Code Online (Sandbox Code Playgroud)

演示后者:

>>> def comma_separator(sequence):
...     if len(sequence) > 1:
...         return '{} and {}'.format(', '.join(sequence[:-1]), sequence[-1])
...     try:
...         return sequence[0]
...     except IndexError:
...         raise ValueError('Must pass in at least one element')
... 
>>> comma_separator(['foo', 'bar', 'baz'])
'foo, bar and baz'
>>> comma_separator(['foo', 'bar'])
'foo and bar'
>>> comma_separator(['foo'])
'foo'
>>> comma_separator([])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in comma_separator
ValueError: Must pass in at least one element
Run Code Online (Sandbox Code Playgroud)


mha*_*wke 6

作为Martijn 可读答案的替代方案,您可以使用两个str.join(); 一个用逗号连接给定序列中除最后一项之外的所有项的内部连接,以及一个and将内部连接的结果与最后一项连接的外部连接。这是一个单行:

def comma_separator(seq):
    return ' and '.join([', '.join(seq[:-1]), seq[-1]] if len(seq) > 2 else seq)

>>> comma_separator([])
''
>>> comma_separator(['a'])
'a'
>>> comma_separator(['a', 'b'])
'a and b'
>>> comma_separator(['a', 'b', 'c'])
'a, b and c'
>>> comma_separator(['a', 'b', 'c', 'd'])
'a, b, c and d'
Run Code Online (Sandbox Code Playgroud)

这不会将空序列视为错误,而是返回一个空字符串。