Antoine Gallix
Antoine Gallix

Reputation: 816

"list comprehension"-style syntax outside list?

I find the list comprehension syntax very useful and compact. After using it all the time, it makes me want to use it outside lists, for example I would like to change:

s="sausages hamsters"
intermediate=" and "
word1,word2=s.split()
s2=word1+intermediate+word2

into

word1,word2=s.split()
s2=word1+intermediate+word2 for word1,word2 in s.split

obviously it doesn't work. Am I missing something here or this simply cannot be done in one line?

Edit : Of course this example is stupid but in some cases I can see this saving more than one line

Edit : I just wrote the example to make it more pleasant to read but the more litteral version of my question would be:

"Is there a way to create a variable this way, in one declaration:

newVar= <expression using still undefined variables> \  
        <some keyword or symbols> \  
         <declaration of pre-cited undefined variables>

just like the list comprehension allows to do:

newList=[<expression using still undefined variables>  
    for <declaration of pre-cited undefined variables, as result of an iterator>]

If we can do it to build lists, is it possible also for simple single objects?"

Upvotes: 1

Views: 988

Answers (3)

jme
jme

Reputation: 20745

Sure, you could do something like:

s = "sausages hamsters"
intermediate = " and "
(result,) = [w1 + intermediate + w2 for w1,w2 in [s.split()]]

But I'm not entirely sure what you'd gain by doing so. The join and format examples above are preferable.

Upvotes: 1

Martijn Pieters
Martijn Pieters

Reputation: 1123420

You want str.join() here:

' and '.join(s.split())

Whenever you want to concatenate multiple strings, with or without text in between the strings, str.join() is going to be faster choice over per-string concatenation.

Since str.join() takes an iterable argument, you can use generator expressions and list comprehensions to your hearts content. A list comprehension would be preferable (as it is faster for str.join())

As for a more 'general' list comprehension-like syntax; between generator expressions, the various comprehension formats (list, set, and dict) and the next() function, you really don't need more complicated syntax still.

Remember that readability counts too; don't try and apply looping where looping makes no sense. As an anti-pattern, your 'one object from a loop' example could be:

result = next(a + foo + b for a, b in (s.split(),))

where I shoehorned a separate assignment of the s.split() result into a look in a generator expression. The expression is very hard to parse, and you should not use this just for the sake of wanting to use loops where no loop is needed.

Upvotes: 5

thefourtheye
thefourtheye

Reputation: 239573

s, intermediate = "sausages hamsters", "and"
print "{1} {0} {2}".format(intermediate, *s.split())
# sausages and hamsters

Since we use template string approach, we can change the intermediate value also as we like.

As @Martijn suggested, you can do

print " {} ".format(intermediate).join(s.split())

Upvotes: 1

Related Questions