petobens petobens - 4 months ago 8
Python Question

Join author names with first ones separated by comma and last one by "and"

I'm completely new to Python and have a list of names separated by

\and
, which I need to join separating the first ones with comma and the last one by 'and'. However if there are more than 4 names the return value should be the first name along with the phrase 'et al.'. So if I have

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


I should get 'John Bar et al.'. Whereas with

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


I should get 'John Bar, Tom Foo and Sam Foobar'.

It should also work with just one author name, returning that single name (and surname) by itself.

I tried doing something like

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


But that obviously doesn't work. So my question is how can I use
join
and
split
to get the first authors separated by comma and the last by 'and' taking into account that if there are more than four authors only the first author name should be returned along with 'et al.'.

Answer

Start with splitting out the names:

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

Then rejoin based on the length:

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]

This works for entries with just one author too; we just reassign the name to authors.

Combined into a function:

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]

with a demo:

>>> 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'
Comments