I don't know if this is a line of code you want to keep in your program, maybe your method was more simple and readable.
What iI do here is create a list comprehension with all the values in the spam list but iI add the item as "{spam[i]}," if is not the last value (i < len(spam) - 1) and as "and {spam[i]}" if it is the last value, then you can directly join the element of the new list with .join().join() method.
def list_to_string(spam: list) -> str:
return " ".join([f"{spam[i]}," if i < len(spam) - 1 else f"and {spam[i]}" for i in range(len(spam))])
This is equal to this code:
def list_to_string(spam: list) -> str:
new_list = []
for i in range(len(spam)):
if i < len(spam) - 1:
new_list.append(f"{spam[i]},")
else:
new_list.append(f"and {spam[i]}")
return " ".join(new_list)
And equal to this code:
def list_to_string(spam: list) -> str:
new_list = []
for i in range(len(spam)):
new_list.append(f"{spam[i]}," if i < len(spam) - 1 else f"and {spam[i]}")
return " ".join(new_list)
Edit: note that if the list include only one item the resulting string will be "and item" like your initial request state:
with and inserted before the last item.