How to join list in Python but make the last separator different?

后端 未结 8 1612
一向
一向 2020-11-28 15:28

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.

         


        
相关标签:
8条回答
  • 2020-11-28 16:04

    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([]) == ''
    
    0 讨论(0)
  • 2020-11-28 16:06
    ('{}, '*(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.

    0 讨论(0)
  • 2020-11-28 16:07

    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.

    0 讨论(0)
  • 2020-11-28 16:10

    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

    0 讨论(0)
  • 2020-11-28 16:14

    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.

    0 讨论(0)
  • 2020-11-28 16:15
    "&".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)
    
    0 讨论(0)
提交回复
热议问题