Reputation: 52293
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?
But islice may be even worse since it iterates through the start of the list: itertools.islice compared to list slice
Some alternatives are discussed here: Avoiding unnecessary slice copying in Python
Upvotes: 3
Views: 16177
Reputation: 131610
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.
Upvotes: 5
Reputation: 879919
Also riffing on David Zaslavsky answer:
string = '.'.join([string] + list_ + [suffix])
The advantage of doing it this way is that there is no addition of strings.
Upvotes: 4
Reputation: 27343
If list_
is a generator (or can be trivially changed to be one), you can get away without materializing any lists at all using chain()
from itertools
.
from itertools import chain
'.'.join(chain(('',),list_,(suffix,)))
(This takes inspiration from David Zaslavsky's answer.)
Upvotes: 4
Reputation: 33407
string += ('.' + '.'.join(list_) if list_ else '') + '.' + suffix
Upvotes: 1