Printing a list as "a, b, c." using Python
TL;DR:

Despite this being the currently accepted &amp; highest voted answer, these methods from this answer and variations (1, 2) of it:

print(", ".join(flavours) + ".")         # Peilonrayz
print(", ".join(flavours), end=".\n")    # Maarten Fabré
print(f'{", ".join(flavors)}.')          # Andy


are all faster than the solution originally proposed in this answer:

print(*flavours, sep=', ', end='.\n')




Original Answer, Plus Explanation &amp; Timing Analysis:

Consider also:

flavours = ['chocolate', 'vanilla', 'caramel', 'strawberry', 'coffee']
print(*flavours, sep=', ', end='.\n')


This does not perform any unnecessary string concatenation, nor does it require a loop variable to test for the final index. 



How does this work?

The print function takes a variable number of arguments, and so would be defined something like:

def print(*args, sep=' ', end='\n', file=sys.stdout, flush=False):
    # ...


except it is a built-in function.

The *args parameter consumes all of the unnamed arguments into one list for processing by the function, allowing the function to take a variable number of arguments.

In the statement,

print(*flavours, sep=', ', end='.\n')


The "splat operator" (*) takes the iterable flavours and expands it into a list of arguments for the function, allowing the caller to pass a variable number of arguments to a function, taken from the contents of a container (list, tuple, etc).

The Python interpreter could match the *flavours splat operator with the *args variable argument list of the print function, and simply pass the flavours list into the args.

But does it?  I got worried.  Perhaps, because a list is given, and the variable argument list (in CPython) is passed as a tuple, the list actually must be copied.  How much time does it take.

After creating a class Null output stream, to speed up the printing, I began passing variable sized lists to the various answers, and profiling the results.  While my solution is one of the least amounts of code, it turns out that @Peilonrayz's solution of ", ".join(flavours) seems to be the fastest.



Using tuples or lists doesn't seem to affect the performance much, so any thought that splatting a tuple instead of a list, to be collected into a *args variable argument tuple may be optimized to a no-op, seems to have been squashed.



Since print will automatically convert objects to strings for printing, the above will work for all object types in a list.  The ", ".join(flavours) will only work for strings; it would have to be modified to convert non-strings to strings to be truly equivalent:

print(", ".join(map(str, flavours)) + ".")