Python join list of strings with comma but with so

2019-05-20 06:42发布

Assume i have this list l:

l = ['a', 'b', 'c', 'd', 'e']

I know i can join them using .join with comma separated as:

s = ', '.join(l)
>>> a, b, c, d, e

But i want to respect these conditions while joining, few cases are:

  • If len(l) == 1 then output should be just a
  • if len(l) == 2 then output should be a and b
  • if len(l) > 2 and len(l) < 5 then output should be a, b, c and d
  • if len(l) >= 5:
    • if len(l) == 5 then output should be a, b, c, d and 1 other
    • if len(l) > 5 then output should be a, b, c, d and +(number of remaining strings) others

What i have tried (working):

def display(l, threshold=4):
    s = ''
    if l:
        c = len(l)
        if c <= threshold:
            if c == 1:
                s = l[0]
            else:
                s = ', '.join(l[:-1])
                s += ' and ' + l[-1]
        else:
            s = ', '.join(l[:threshold])
            remaining = c - threshold
            other = 'other' if remaining == 1 else 'others'
            remaining = str(remaining) if remaining == 1 else '+' + str(remaining)
            s += ' and %s %s' % (remaining, other)
        print s
    return s

if __name__ == '__main__':
    l = ['a', 'b', 'c', 'd', 'e', 'f']
    display(l[:1])
    display(l[:2])
    display(l[:3])
    display(l[:4])
    display(l[:5])
    display(l)

Output:

a
a and b
a, b and c
a, b, c and d
a, b, c, d and 1 other
a, b, c, d and +2 others

Can this code be improved and refractor?

4条回答
混吃等死
2楼-- · 2019-05-20 06:46
def display(l, t = 5):
    length = len(l)
    if   length <= 2:         print " and ".join(l)
    elif length < threshold:  print ", ".join(l[:-1]) + " and " + l[-1]
    elif length == threshold: print ", ".join(l[:-1]) + " and 1 other"
    else: print ", ".join(l[:t-1]) + " and +{} others".format(length - (t - 1))

Output

a
a and b
a, b and c
a, b, c and d
a, b, c, d and 1 other
a, b, c, d and +2 others
查看更多
趁早两清
3楼-- · 2019-05-20 06:48

Just a thought (maybe over-complicated)

def join_func(inlist, threshold=5):
    llen = len(inlist)
    if llen==1:
        return inlist[0]
    suffix_len = llen - threshold
    prefix = ','.join(inlist[:min(llen, threshold)-1*(suffix_len<=0)])
    return ' and '.join([prefix, inlist[-1] if suffix_len<=0 else 
                                 '{} other{}'.format(suffix_len, 's'*(suffix_len>1))])

Some test

In [69]: for l in xrange(1, 8):
    print join_func(list(string.ascii_letters[:l]))
   ....:     
a
a and b
a,b and c
a,b,c and d
a,b,c,d and e
a,b,c,d,e and 1 other
a,b,c,d,e and 2 others
查看更多
老娘就宠你
4楼-- · 2019-05-20 06:59

This does just what you wanted:

def frmt_lst(l, limit=5):
    if len(l) == 1:
        return l[0]
    if len(l) < limit:
        return '{} and {}'.format(', '.join(l[:-1]), l[-1])
    if len(l) == limit:
        return '{} and 1 other'.format(', '.join(l[:-1]))
    if len(l) > limit:
        return '{} and {} others'.format(', '.join(l[:limit-1]), len(l[limit-1:]))

print frmt_lst(['a'])
print frmt_lst(['a', 'b'])
print frmt_lst(['a', 'b', 'c'])
print frmt_lst(['a', 'b', 'c', 'd'])
print frmt_lst(['a', 'b', 'c', 'd', 'e'])
print frmt_lst(['a', 'b', 'c', 'd', 'e', 'f'])

>>> 
a
a and b
a, b and c
a, b, c and d
a, b, c, d and 1 other
a, b, c, d and 2 others

I noticed you only really had four special cases. So I changed the code to be easier.

查看更多
戒情不戒烟
5楼-- · 2019-05-20 07:09
def frm_list(l, limit=5):
    length = len(l)
    if length == 1:
        return l[0]

    if length > limit:
        l_joins = ', '.join(l[:limit-1])
        others = length - limit
        plural = others > 1 and 's' or ''
        return u'{} and {} other{}'.format(l_joins, others, plural)

    l_joins = ', '.join(l[:-1])
    return u'{} and {}'.format(l_joins, l[-1])
查看更多
登录 后发表回答