I\'m trying to turn a list into separated strings joined with an ampersand if there are only two items, or commas and an ampersand between the last two e.g.
It looks like while I was working on my answer, someone may have beaten me to the punch with a similar one. Here's mine for comparison. Note that this also handles cases of 0, 1, or 2 members in the list.
# Python 3.x, should also work with Python 2.x.
def my_join(my_list):
x = len(my_list)
if x > 2:
s = ', & '.join([', '.join(my_list[:-1]), my_list[-1]])
elif x == 2:
s = ' & '.join(my_list)
elif x == 1:
s = my_list[0]
else:
s = ''
return s
assert my_join(['Jim', 'Jack', 'John']) == 'Jim, Jack, & John'
assert my_join(['Jim', 'Jack']) == 'Jim & Jack'
assert my_join(['Jim',]) == 'Jim'
assert my_join([]) == ''
('{}, '*(len(authors)-2) + '{} & '*(len(authors)>1) + '{}').format(*authors)
This solution can handle a list of authors of length > 0, though it can be modified to handle 0-length lists as well. The idea is to first create a format string that we can format by unpacking list. This solution avoids slicing the list so it should be fairly efficient for large lists of authors.
First we concatenate '{}, ' for every additional author beyond two authors. Then we concatenate '{} & ' if there are two or more authors. Finally we append '{}' for the last author, but this subexpression can be '{}'*(len(authors)>0) instead if we wish to be able to handle an empty list of authors. Finally, we format our completed string by unpacking the elements of the list using the * unpacking syntax.
If you don't need a one-liner, here is the code in an efficient function form.
def format_authors(authors):
n = len(authors)
if n > 1:
return ('{}, '*(n-2) + '{} & {}').format(*authors)
elif n > 0:
return authors[0]
else:
return ''
This can handle a list of authors of any length.
Here is a one line example that handles all the edge cases (empty list, one entry, two entries):
' & '.join(filter(None, [', '.join(my_list[:-1])] + my_list[-1:]))
The filter() function is used to filter out the empty entries that happens when my_list is empty or only has one entry.
Here's a simple one that also works for empty or 1 element lists:
' and '.join([', '.join(mylist[:-1])]+mylist[-1:])
The reason it works is that for empty lists both [:-1] and [-1:] give us an empty list again
You could break this up into two joins. Join all but the last item with ", ". Then join this string and the last item with " & ".
all_but_last = ', '.join(authors[:-1])
last = authors[-1]
' & '.join([all_but_last, last])
Note: This doesn't deal with edge cases, such as when authors is empty or has only one element.
"&".join([",".join(my_list[:-1]),my_list[-1]])
I would think would work
or maybe just
",".join(my_list[:-1]) +"&"+my_list[-1]
to handle edge cases where only 2 items you could
"&".join([",".join(my_list[:-1]),my_list[-1]] if len(my_list) > 2 else my_list)