Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Concatenate a list of items with more advanced separator control
def join_plus(items, separator, final_separator=None, pair_separator=None):
"""Concatenate a list of items with more advanced separator control.
Example 1 - You have a list of names = [Tom, Jeff, Sally] and want them
combined as a string. There are a few possible desired outputs:
(1-1) Tom, Jeff, Sally # join_plus(names, ', ')
(1-2) Tom, Jeff, and Sally # join_plus(names, ', ', final_separator=', and ')
Example 2 - Same but with two names = [Tom, Jeff]. This creates a third
possible output, which I think is most desirable.
(2-1) Tom, Jeff # join_plus(names, ', ')
(2-2) Tom, and Jeff # join_plus(names, ', ', final_separator=', and ')
(2-3) Tom and Jeff # join_plus(names, ', ', pair_separator=' and ')
But `str.join(...)` does not support the special cases in 1-2, 2-2, or
2-3. You're left to handle multiple different joins at app logic level.
This is an attempt at a better way.
In non-special cases, `join_plus(...)` should behave exactly like
`str.join(...)`.
"""
if not final_separator:
final_separator = separator
if len(items) <= 2:
if pair_separator is None:
all_items = final_separator.join(items)
else:
all_items = pair_separator.join(items)
else:
last_two_items = final_separator.join(items[-2:])
beginning_items = separator.join(items[:-2])
all_items = separator.join([beginning_items, last_two_items])
return all_items
def main():
# tests - does it behave like join with the simplest input?
assert join_plus([''], ', ') == ', '.join([''])
assert join_plus(['a'], ', ') == ', '.join(['a'])
assert join_plus(['a', 'b'], ', ') == ', '.join(['a', 'b'])
assert join_plus(['a', 'b', 'c'], ', ') == ', '.join(['a', 'b', 'c'])
# tests - final separation
assert join_plus(['a'], ', ', final_separator=', and ') == 'a'
assert join_plus(['a', 'b'], ', ', final_separator=', and ') == 'a, and b'
assert join_plus(['a', 'b', 'c'], ', ', final_separator=', and ') == 'a, b, and c'
assert join_plus(['a', 'b', 'c', 'd', 'e'], ', ', final_separator=', and ') == 'a, b, c, d, and e'
assert join_plus(['a', 'b', 'c', 'd, e'], ', ', final_separator=', and ') == 'a, b, c, and d, e'
# tests - pair separation
assert join_plus(['a', 'b'], ', ', pair_separator=' and ') == 'a and b'
# tests - final and pair separation together
assert join_plus(['a', 'b'], ', ', pair_separator=' and ', final_separator=', and ') == 'a and b'
assert join_plus(['a', 'b', 'c', 'd', 'e'], ', ', pair_separator=' and ', final_separator=', and ') == 'a, b, c, d, and e'
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment