join with a separator added at the end when not empty
Question: I need to append all elements in `list_` to a `string`; at the end I need to
add a suffix. A dot '.' has to separate all elements:

    
    
    list_ = args[f(n) : f(n+1)]
    if list_:
      string += '.' + '.'.join(list_) + '.' + suffix # works except when list_ is empty
    else:
      string += '.' + suffix
    # list_ isn't used after this
    

Can I rewrite it in a simpler way in one line? If `join` added a separator
after each element, it would just this:

    
    
    string += '.' + '.'.join(args[f(n) : f(n+1)]) + '.' + suffix
    

Edit

I just learned that:

Slices are copies even if they are never assigned to: [Does Python do slice-
by-reference on strings?](http://stackoverflow.com/questions/5722006/does-
python-do-slice-by-reference-on-strings)

But islice may be even worse since it iterates through the start of the list:
[itertools.islice compared to list
slice](http://stackoverflow.com/questions/2738096/itertools-islice-compared-
to-list-slice)

Some alternatives are discussed here: [Avoiding unnecessary slice copying in
Python](http://stackoverflow.com/questions/2328171/avoiding-unnecessary-slice-
copying-in-python)


Answer: I would go with this (updated to reflect edits to the question):

    
    
    '.'.join([''] + args[f(n):f(n+1)] + [suffix])
    

_EDIT_ : taking inspiration from sblom's and unutbu's answers, I might
_actually_ do this:

    
    
    from itertools import chain, islice
    string = '.'.join(chain([string],  islice(args, f(n), f(n+1)), [suffix]))
    

if I were concerned about the memory cost of slicing `args`. You can use a
tuple `(string,)` or a list `[string]` for the string and the suffix; given
that they're one element each, there's no significant difference in memory
usage or execution time, and since they're not being stored, you don't have to
worry about mutability. I find the list syntax a little cleaner.

However: I'm not sure if Python actually creates a new list object for a slice
that is only going to be used, not assigned to. If it doesn't, then given that
`args` is a proper list, using `islice` over `[f(n):f(n+1)]`doesn't save you
much of anything, and in that case I'd just go with the simple approach (up
top). If `args` were a generator or other lazily evaluated iterable with a
very large number of elements, _then_ `islice` might be worth it.

