Skip to content

Instantly share code, notes, and snippets.

@tedmiston
Created April 4, 2016 03:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tedmiston/c5c36fbaddb5f9f50e4e22eb4188cd51 to your computer and use it in GitHub Desktop.
Save tedmiston/c5c36fbaddb5f9f50e4e22eb4188cd51 to your computer and use it in GitHub Desktop.
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