【问题标题】:Joining words together with a comma, and "and"用逗号和“and”连接单词
【发布时间】:2017-06-15 18:28:31
【问题描述】:

我正在处理“Automate the Boring Stuff with Python”。我不知道如何从下面的程序中删除最终输出逗号。目标是不断提示用户输入值,然后将其打印在列表中,并在末尾插入“and”。输出应如下所示:

apples, bananas, tofu, and cats

我的看起来像这样:

apples, bananas, tofu, and cats,

最后一个逗号把我逼疯了。

def lister():
    listed = []
    while True:
        print('type what you want to be listed or type nothing to exit')
        inputted = input()
        if inputted == '':
            break
        else:
            listed.append(inputted+',')
    listed.insert(-1, 'and')
    for i in listed:
        print(i, end=' ')
lister()

【问题讨论】:

标签: python list


【解决方案1】:

您可以通过将格式推迟到打印时间来避免在列表中的每个字符串中添加逗号。加入除', ' 上的最后一项之外的所有项目,然后使用格式化插入与and 连接的最后一项的加入字符串:

listed.append(inputed)
...
print('{}, and {}'.format(', '.join(listed[:-1]), listed[-1]))

演示:

>>> listed = ['a', 'b', 'c', 'd']
>>> print('{}, and {}'.format(', '.join(listed[:-1]), listed[-1]))
a, b, c, and d

【讨论】:

  • 改进建议:str.format 不再推荐,并且 3.6 增加了对新的内联格式化语法的支持,如果您想使用格式化方法,则使代码更具可读性:f"{', '.join(listed[:-1])}, and {listed[-1]}"。但是,我想说根本没有格式是最易读的:', '.join(listed[:-1]) + ", and" + listed[-1]
  • @gntskn str.format 真的“不再推荐”吗?我认为格式字符串本身更易于阅读,可以提取到fmt 变量等。我确信f"..." 字符串有用例,尤其是在将局部变量粘贴到格式时字符串,但说“不再推荐”str.format 似乎有点过分了。
  • @ZacCrites 你知道吗,你是对的;我在想% 运算符。这是我在午夜之前从手机发帖得到的:p
  • @gntskn 另请注意,f-strings 在 Python 版本 中不可用
  • 此代码不处理少于 3 个项目的列表。
【解决方案2】:

公认的答案很好,但最好将此功能移动到一个单独的函数中,该函数接受一个列表,并处理列表中 0、1 或 2 个项目的边缘情况:

def oxfordcomma(listed):
    if len(listed) == 0:
        return ''
    if len(listed) == 1:
        return listed[0]
    if len(listed) == 2:
        return listed[0] + ' and ' + listed[1]
    return ', '.join(listed[:-1]) + ', and ' + listed[-1]

测试用例:

>>> oxfordcomma([])
''
>>> oxfordcomma(['apples'])
'apples'
>>> oxfordcomma(['apples', 'pears'])
'apples and pears'
>>> oxfordcomma(['apples', 'pears', 'grapes'])
'apples, pears, and grapes'

【讨论】:

  • 良好的模块化。对于一般情况,我认为我更喜欢通过列表加入以and 为前缀的最后一项,因此join 与其余部分一起添加逗号:', '.join(listed[:-1] + [f'and {listed[-1]}'])... 但这似乎是简单的审美选择。
【解决方案3】:

这将删除最后一个单词的逗号。

listed[-1] = listed[-1][:-1]

它的工作方式是listed[-1] 从列表中获取最后一个值。我们使用= 将此值分配给listed[-1][:-1],这是列表中最后一个单词的一部分,包含最后一个字符之前的所有内容。

如下图实现:

def lister():
    listed = []
    while True:
        print('type what you want to be listed or type nothing to exit')
        inputted = input()
        if inputted == '':
            break
        else:
            listed.append(inputted+',')
    listed.insert(-1, 'and')
    listed[-1] = listed[-1][:-1]
    for i in listed:
        print(i, end=' ')
lister()

【讨论】:

  • 所以这就像一个魅力,谢谢你的回答,但我不明白这个 (listed[-1] =listed[-1][:-1]) 有什么作用
  • @Admin_Who 我为你的答案添加了解释。
【解决方案4】:

稍微修改你的代码...

def lister():
    listed = []
    while True:
        print('type what you want to be listed or type nothing to exit')
        inputted = input()
        if inputted == '':
            break
        else:
            listed.append(inputted) # removed the comma here

    print(', '.join(listed[:-2]) + ' and ' + listed[-1])  #using the join operator, and appending and xxx at the end
lister()

【讨论】:

  • 您需要更多:OP 已经在各个字符串中插入了逗号。
  • 这将在and后面添加一个逗号。
【解决方案5】:
listed[-1] = listed[-1][:-1]

这将截断listed中最后一个字符串的最后一个字符。

【讨论】:

    【解决方案6】:

    有很多方法可以做到,但是这个怎么样?

    # listed[-1] is the last element of the list
    # rstrip removes matching characters from the end of the string
    listed[-1] = listed[-1].rstrip(',')
    listed.insert(-1, 'and')
    for i in listed:
        print(i, end=' ')
    

    你仍然会在行尾打印一个空格,但我猜你不会看到它,因此不会在意。 :-)

    【讨论】:

      【解决方案7】:

      我会使用 f 字符串(formatted string literal,在 Python 3.6+ 中可用):

      def grammatically_join(words, oxford_comma=False):
          if len(words) == 0:
              return ""
          if len(words) == 1:
              return listed[0]
          if len(words) == 2:
              return f"{listed[0]} and {listed[1]}"
          return f'{", ".join(words[:-1])}{"," if oxford_comma else ""} and {words[-1]}'
      

      如果您不需要Oxford comma,那么您可以简化代码并删除len(words) == 2 的额外边缘情况:

      def grammatically_join(words):
          if len(words) == 0:
              return ""
          if len(words) == 1:
              return listed[0]
          return f'{", ".join(words[:-1])} and {words[-1]}'
      

      【讨论】:

        【解决方案8】:

        假设如果只有两个项目,你可以用逗号,这是相当紧凑的:

        def commaize(items):
            return ', and'.join(', '.join(items).rsplit(',', 1))
        

        行为如下:

        >>> commaize([])
        ''
        >>> commaize(['apples'])
        'apples'
        >>> commaize(['apples', 'bananas'])
        'apples, and bananas'
        >>> commaize(['apples', 'bananas', 'tofu', 'cats'])
        'apples, bananas, tofu, and cats'
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2018-01-29
          • 2021-10-16
          • 2011-07-02
          • 1970-01-01
          • 1970-01-01
          • 2022-01-16
          • 2011-01-01
          相关资源
          最近更新 更多