11
\$\begingroup\$

I looking over some old code, I had written the function below with a C-style for-loop iterating over a count variable. I then fixed it up with new knowledge, but still am suspicious that there is even a better way to do this.

The function should behave like so:

>>> join_list(['a'])
'a'
>>> join_list(['a', 'b'])
'a or b'
>>> join_list(['a', 'b', 'c'])
'a, b, or c'

The function I have currently:

def join_list(my_list):
    length = len(my_list)
    if length == 1:
        return my_list[0]
    elif length == 2:
        return ' or '.join(my_list)
    else:
        head = ', '.join(my_list[:-1])
        return head + ', or ' + my_list[-1]
\$\endgroup\$
2
  • \$\begingroup\$ There's no docstring! \$\endgroup\$ – Gareth Rees Feb 8 '14 at 10:28
  • \$\begingroup\$ To be fair I defined this function within my if __name__ == '__main__' conditional, but I digress I think the code speaks for itself :). \$\endgroup\$ – Winny Feb 8 '14 at 17:34
8
\$\begingroup\$

Looks pretty good. The only problem I can see is that you're not doing a check to make sure the list is not empty: if it is, then you'll try to access my_list[-1] in the final else clause, which will raise an IndexError.

Hence, I'd simply add a check up front for length == 0 and return '' in that case.

\$\endgroup\$
2
  • 1
    \$\begingroup\$ if you handle 2 and 3 item cases first you can fall through to ''.join(my_list) which covers both 0 and 1 \$\endgroup\$ – theodox Feb 8 '14 at 17:41
  • \$\begingroup\$ I like that a lot, but I want to test for least first. All I need to change is the first clause to if length <= 1: ''.join(my_list) \$\endgroup\$ – Winny Feb 8 '14 at 18:06
2
\$\begingroup\$

You could also write, a bit shorter:

def join_list(items):
    if not items:
        return ''
    *init, last = map(str, items)
    return (', '.join(init) + ' or '*bool(init) + last)

Example:

>>> join_list(range(5))
'0, 1, 2, 3 or 4'
\$\endgroup\$
2
  • \$\begingroup\$ I tested that on Python 2.7.6 and Python 3.3. Looks like the asterisk in *init, last = map(str, items) raises a SyntaxError on Python 2.7.6. Do you know what that feature of Python 3.3 is called? \$\endgroup\$ – Winny Feb 9 '14 at 4:49
  • 1
    \$\begingroup\$ @Winny Sorry, forgot to mention its python3 code. Its called extended unpacking (pep 3132). \$\endgroup\$ – Lennart_96 Feb 10 '14 at 9:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.