Tweak iter_to_string to be a little more flexible about limiters

This commit is contained in:
Griatch 2021-12-11 10:48:18 +01:00
parent 1400436c11
commit affa3b8cf7
2 changed files with 31 additions and 20 deletions

View file

@ -12,7 +12,6 @@ import mock
from datetime import datetime, timedelta from datetime import datetime, timedelta
from django.test import TestCase from django.test import TestCase
from datetime import datetime
from twisted.internet import task from twisted.internet import task
from evennia.utils.ansi import ANSIString from evennia.utils.ansi import ANSIString
@ -74,7 +73,7 @@ class TestListToString(TestCase):
self.assertEqual('"1", "2", "3"', utils.list_to_string([1, 2, 3], endsep="", addquote=True)) self.assertEqual('"1", "2", "3"', utils.list_to_string([1, 2, 3], endsep="", addquote=True))
self.assertEqual("1, 2, and 3", utils.list_to_string([1, 2, 3])) self.assertEqual("1, 2, and 3", utils.list_to_string([1, 2, 3]))
self.assertEqual( self.assertEqual(
'"1", "2", and "3"', utils.list_to_string([1, 2, 3], endsep="and", addquote=True) '"1", "2" and "3"', utils.list_to_string([1, 2, 3], endsep="and", addquote=True)
) )
self.assertEqual("1 and 2", utils.list_to_string([1, 2])) self.assertEqual("1 and 2", utils.list_to_string([1, 2]))

View file

@ -359,14 +359,14 @@ def columnize(string, columns=2, spacing=4, align="l", width=None):
return "\n".join(rows) return "\n".join(rows)
def iter_to_str(initer, endsep="and", addquote=False): def iter_to_str(iterable, endsep=", and", addquote=False):
""" """
This pretty-formats an iterable list as string output, adding an optional This pretty-formats an iterable list as string output, adding an optional
alternative separator to the second to last entry. If `addquote` alternative separator to the second to last entry. If `addquote`
is `True`, the outgoing strings will be surrounded by quotes. is `True`, the outgoing strings will be surrounded by quotes.
Args: Args:
initer (any): Usually an iterable to print. Each element must be possible to iterable (any): Usually an iterable to print. Each element must be possible to
present with a string. Note that if this is a generator, it will be present with a string. Note that if this is a generator, it will be
consumed by this operation. consumed by this operation.
endsep (str, optional): If set, the last item separator will endsep (str, optional): If set, the last item separator will
@ -377,35 +377,47 @@ def iter_to_str(initer, endsep="and", addquote=False):
Returns: Returns:
str: The list represented as a string. str: The list represented as a string.
Notes:
Default is to use 'Oxford comma', like 1, 2, 3, and 4. To remove, give
`endsep` as just `and`.
Examples: Examples:
```python ```python
>>> list_to_string([1,2,3], endsep='') >>> list_to_string([1,2,3], endsep='')
'1, 2, 3' '1, 2, 3'
>>> list_to_string([1,2,3], ensdep='and') >>> list_to_string([1,2,3], ensdep='and')
'1, 2, and 3' '1, 2 and 3'
>>> list_to_string([1,2,3], endsep='and', addquote=True) >>> list_to_string([1,2,3], endsep=', and', addquote=True)
'"1", "2", and "3"' '"1", "2", and "3"'
``` ```
""" """
if endsep: if not iterable:
endsep = " " + endsep
if not initer:
return "" return ""
initer = tuple(str(val) for val in make_iter(initer)) len_iter = len(iterable)
if addquote: if addquote:
if len(initer) == 1: iterable = tuple(f'"{val}"' for val in make_iter(iterable))
return '"%s"' % initer[0]
elif len(initer) == 2:
return '"%s"' % ('"%s "' % endsep).join(str(v) for v in initer)
return ", ".join('"%s"' % v for v in initer[:-1]) + ",%s %s" % (endsep, '"%s"' % initer[-1])
else: else:
if len(initer) == 1: iterable = tuple(str(val) for val in make_iter(iterable))
return str(initer[0])
elif len(initer) == 2: if endsep.startswith(","):
return ("%s " % endsep).join(str(v) for v in initer) # oxford comma alternative
return ", ".join(str(v) for v in initer[:-1]) + ",%s %s" % (endsep, initer[-1]) endsep = endsep[1:] if len_iter < 3 else endsep
elif endsep:
# normal space-separated end separator
endsep = " " + str(endsep).strip()
else:
# no separator given - use comma
endsep = ','
if len_iter == 1:
return str(iterable[0])
elif len_iter == 2:
return f"{endsep} ".join(str(v) for v in iterable)
else:
return ", ".join(str(v) for v in iterable[:-1]) + f"{endsep} {iterable[-1]}"
# legacy aliases # legacy aliases