-2

我对 Python 完全陌生,并且有一个用 分隔的名称列表\and,我需要将第一个用逗号分隔,最后一个用“和”分隔。但是,如果名称超过 4 个,则返回值应该是第一个名称以及短语“et al.”。所以如果我有

 authors = 'John Bar \and Tom Foo \and Sam Foobar \and Ron Barfoo'

我应该得到“John Bar et al.”。而随着

authors = 'John Bar \and Tom Foo \and Sam Foobar'

我应该得到“John Bar、Tom Foo 和 Sam Foobar”。

它还应该只使用一个作者姓名,并单独返回该单一姓名(和姓氏)。

我试着做类似的事情

  names = authors.split('\and')
  result = ', '.join(names[:-1]) + ' and '.join(names[-1])

但这显然行不通。所以我的问题是我如何使用joinsplit让第一作者用逗号分隔,最后一个作者用“和”分隔,考虑到如果有超过四个作者,只有第一作者姓名应该与“等”一起返回。 .

4

5 回答 5

9

从拆分名称开始:

names = [name.strip() for name in authors.split(r'\and')]  # assuming a raw \ here, not the escape code \a.

然后根据长度重新加入:

if len(names) >= 4:
    authors = '{} et al.'.format(names[0])
elif len(names) > 1:
    authors = '{} and {}'.format(', '.join(names[:-1]), names[-1])
else:
    authors = names[0]

这也适用于只有一位作者的条目;我们只是将名称重新分配给authors.

组合成一个函数:

def reformat_authors(authors):
    names = [name.strip() for name in authors.split(r'\and')]
    if len(names) >= 4:
        return '{} et al.'.format(names[0])
    if len(names) > 1:
        return '{} and {}'.format(', '.join(names[:-1]), names[-1])
    return names[0]

带演示:

>>> reformat_authors(r'John Bar \and Tom Foo \and Sam Foobar \and Ron Barfoo')
'John Bar et al.'
>>> reformat_authors(r'John Bar \and Tom Foo \and Sam Foobar')
'John Bar, Tom Foo and Sam Foobar'
>>> reformat_authors(r'John Bar \and Tom Foo')
'John Bar and Tom Foo'
>>> reformat_authors(r'John Bar')
'John Bar'
于 2013-04-04T14:21:46.387 回答
2

让我们把这个问题分成几个部分:

首先,获取单个作者的列表:

>>> authors = 'John Bar \\and Tom Foo \\and Sam Foobar \\and Ron Barfoo'
>>> authorlist = [item.strip() for item in authors.split("\\and")]
>>> authorlist
['John Bar', 'Tom Foo', 'Sam Foobar', 'Ron Barfoo']

现在检查列表中的条目数并采取相应措施:

>>> if len(authorlist) > 3:
...     print("{0} et al.".format(authorlist[0]))
... elif len(authorlist) == 1:
...     print(authorlist[0])
... else:
...     print("{0} and {1}".format(", ".join(authorlist[:-1]), authorlist[-1]))
...
John Bar et al.
于 2013-04-04T14:21:24.820 回答
1
def natural_join(val, cnj="and"):
    if isinstance(val, list):
        return " ".join((", ".join(val[0:-1]), "%s %s" % (cnj, val[-1]))) if len(val) > 1 else val[0]
    else:
        return val

natural_join(['pierre'])
# 'pierre'

natural_join(['pierre', 'paul'])
# 'pierre and paul'

natural_join(['pierre', 'paul', 'jacques'])
# 'pierre, paul and jacques'

natural_join(['pierre', 'paul', 'jacques'], cnj="et")
# 'pierre, paul et jacques'
于 2013-04-28T20:58:32.790 回答
0

首先,您应该拆分您的字符串,以使用split.

parts = author.split(' \and ')

然后你应用你的条件:

  1. 如果有 4 个或更多名称,则返回第一个名称 + 'el at'

    if len(parts) >= 4:
        return parts[0]+' et al'
    
  2. 如果有超过 1 个名字,用 ', ' 连接它们,最后一个用 ' 和 ' 连接

    elif len(parts) > 1:
        return ' and '.join([', '.join(parts[:-1]), parts[-1]])
    
  3. 如果只有一个名称,则返回该名称。

    return parts[0] 
    

最终功能:

def my_func(author):
    parts = author.split(' \and ')
    if len(parts) >= 4:
        return parts[0]+' et al'
    elif len(parts) > 1:
        return ' and '.join([', '.join(parts[:-1]), parts[-1]])
    return parts[0] 
于 2013-04-04T14:20:11.810 回答
0

看起来你应该检查一下string.split方法。这里有几个案例:要么有一个名字,要么有 2-3 个名字,要么有 4 个以上的名字。这些中的每一个都需要单独处理,因此只需弄清楚每种情况下需要做什么:

# First split up the names by your specified delimiter (and strip off whitespace)
names = [name.strip() for name in authors.split(r'\and')]

# Now deal with your three cases for formatting.
if len(names) == 1:
    print names[0]
elif len(names) < 4:
    print ', '.join(names[:-1])+' and '+names[-1]
else:
    print names[0]+' et al.'
于 2013-04-04T14:20:47.640 回答