Skip to content

Commit 0cedecf

Browse files
committed
feat: add conjunction parameter to natural_list
1 parent bde649f commit 0cedecf

2 files changed

Lines changed: 28 additions & 5 deletions

File tree

src/humanize/lists.py

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,11 @@
99
__all__ = ["natural_list"]
1010

1111

12-
def natural_list(items: list[Any]) -> str:
12+
def natural_list(items: list[Any], *, conjunction: str = "and") -> str:
1313
"""Natural list.
1414
15-
Convert a list of items into a human-readable string with commas and 'and'.
15+
Convert a list of items into a human-readable string with commas and a
16+
conjunction.
1617
1718
Examples:
1819
>>> natural_list(["one", "two", "three"])
@@ -21,16 +22,22 @@ def natural_list(items: list[Any]) -> str:
2122
'one and two'
2223
>>> natural_list(["one"])
2324
'one'
25+
>>> natural_list(["one", "two", "three"], conjunction="or")
26+
'one, two or three'
2427
2528
Args:
2629
items (list): An iterable of items.
30+
conjunction (str): The word used to join the last item, defaults to 'and'.
2731
2832
Returns:
29-
str: A string with commas and 'and' in the right places.
33+
str: A string with commas and the conjunction in the right places.
3034
"""
3135
if len(items) == 1:
3236
return str(items[0])
3337
elif len(items) == 2:
34-
return f"{str(items[0])} and {str(items[1])}"
38+
return f"{str(items[0])} {conjunction} {str(items[1])}"
3539
else:
36-
return ", ".join([str(item) for item in items[:-1]]) + f" and {str(items[-1])}"
40+
return (
41+
", ".join([str(item) for item in items[:-1]])
42+
+ f" {conjunction} {str(items[-1])}"
43+
)

tests/test_lists.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,19 @@ def test_natural_list(
2121
test_args: list[str] | list[int] | list[str | int], expected: str
2222
) -> None:
2323
assert humanize.natural_list(*test_args) == expected
24+
25+
26+
@pytest.mark.parametrize(
27+
"items, conjunction, expected",
28+
[
29+
(["one", "two", "three"], "or", "one, two or three"),
30+
(["one", "two"], "or", "one or two"),
31+
(["one"], "or", "one"),
32+
(["one", "two", "three"], "and also", "one, two and also three"),
33+
(["one", "two", "three"], "and", "one, two and three"),
34+
],
35+
)
36+
def test_natural_list_conjunction(
37+
items: list[str], conjunction: str, expected: str
38+
) -> None:
39+
assert humanize.natural_list(items, conjunction=conjunction) == expected

0 commit comments

Comments
 (0)