【问题标题】:Grammatical List Join in Python [duplicate]Python中的语法列表加入[重复]
【发布时间】:2013-11-07 14:52:21
【问题描述】:

最pythonic的加入列表的方式是什么,以便每个项目之间有逗号,除了最后一个使用“and”的项目?

["foo"] --> "foo"
["foo","bar"] --> "foo and bar"
["foo","bar","baz"] --> "foo, bar and baz"
["foo","bar","baz","bah"] --> "foo, bar, baz and bah"

【问题讨论】:

  • 谁在乎牛津逗号?
  • 本问答不使用Oxford comma。对于使用牛津逗号的问题和答案,请参阅this question

标签: python list


【解决方案1】:

这个表达式做到了:

print ", ".join(data[:-2] + [" and ".join(data[-2:])])

如下所示:

>>> data
    ['foo', 'bar', 'baaz', 'bah']
>>> while data:
...     print ", ".join(data[:-2] + [" and ".join(data[-2:])])
...     data.pop()
...
foo, bar, baaz and bah
foo, bar and baaz
foo and bar
foo

【讨论】:

  • 为什么使用“e for e in”语法?我什至认为这实际上没有必要。
  • 是的;你是对的。正在玩其他东西,但我最终得到的不需要生成器理解部分。固定。
  • +1 用于在使用 "," 进行一般连接之前使用 "and" 连接最后两个。
  • 接受了这个答案,因为它简洁且无需假设即可工作。
【解决方案2】:

试试这个,它会考虑边缘情况并使用format(),以展示另一种可能的解决方案:

def my_join(lst):
    if not lst:
        return ""
    elif len(lst) == 1:
        return str(lst[0])
    return "{} and {}".format(", ".join(lst[:-1]), lst[-1])

按预期工作:

 my_join([])
=> ""
 my_join(["x"])
=> "x"
 my_join(["x", "y"])
=> "x and y"
 my_join(["x", "y", "z"])
=> "x, y and z"

【讨论】:

  • 不像其他答案那么“聪明”,因此是最“pythonic”的解决方案。唯一的一点,我也会在第二个分支中使用format,这样乐趣总是会返回一个字符串。
  • @thg435 我更喜欢可读性而不是“智能”:) 对于第二个分支,一个简单的str() 就可以了
  • +1 因为不尝试像其他人一样聪明......这非常令人沮丧,像当前最受欢迎的答案一样跨代码运行,只是后来发现它有一个错误,由于以下原因没有立即注意到聪明
  • +1 用于测试用例的功能
【解决方案3】:

基于评论的修复导致了这种有趣的方式。它假设要连接的列表的字符串条目中没有逗号(这无论如何都会有问题,所以这是一个合理的假设。)

def special_join(my_list):
    return ", ".join(my_list)[::-1].replace(",", "dna ", 1)[::-1]


In [50]: def special_join(my_list):
        return ", ".join(my_list)[::-1].replace(",", "dna ", 1)[::-1]
   ....:

In [51]: special_join(["foo", "bar", "baz", "bah"])
Out[51]: 'foo, bar, baz and bah'

In [52]: special_join(["foo"])
Out[52]: 'foo'

In [53]: special_join(["foo", "bar"])
Out[53]: 'foo and bar'

【讨论】:

  • special_join(["foo"]) 返回' and foo'...
  • @chepner:“在 Python 文化中,将某事描述为聪明并不被视为恭维。” ;)
【解决方案4】:

已经有了很好的答案。这个适用于所有测试用例,并且与其他一些测试用例略有不同。

def grammar_join(words):
    return reduce(lambda x, y: x and x + ' and ' + y or y,
                 (', '.join(words[:-1]), words[-1])) if words else ''

tests = ([], ['a'], ['a', 'b'], ['a', 'b', 'c'])
for test in tests:                                 
    print grammar_join(test)

a
a and b
a, b and c

【讨论】:

    【解决方案5】:

    只是最后一个的特殊情况。像这样:

    '%s and %s'%(', '.join(mylist[:-1]),mylist[-1])
    

    可能不会有更简洁的方法了。

    这在零情况下也会失败。

    【讨论】:

    • 即使这也太简洁了,因为它假设有 2 个或更多项目。
    【解决方案6】:

    如果您需要不支持负索引的解决方案(即 Django QuerySet)

    def oxford_join(string_list):
        if len(string_list) < 1:
            text = ''
        elif len(string_list) == 1:
            text = string_list[0]
        elif len(string_list) == 2:
            text = ' and '.join(string_list)
        else:
            text = ', '.join(string_list)
            text = '{parts[0]}, and {parts[2]}'.format(parts=text.rpartition(', '))  # oxford comma
        return text
    
    oxford_join(['Apples', 'Oranges', 'Mangoes'])
    

    【讨论】:

    • 如果列表中的项目包含逗号,则中断。
    猜你喜欢
    • 2013-01-26
    • 1970-01-01
    • 2019-08-18
    • 2011-03-04
    • 2013-06-14
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 2014-04-26
    相关资源
    最近更新 更多