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)