1

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?"

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Antoine Gallix
  • 662
  • 1
  • 11
  • 28
  • 1
    If you sincerely want to find out about this style of syntax outside of list comprehensions (so, for example, dictionary or set comprehensions, or generator expressions) then you should spend the time to come up with a better example, or perhaps even multiple examples to really illustrate what you want. The way your question is formed currently, people will interpret your actual desire as trying to find shorter ways to compose *strings only*. – John Y Mar 06 '14 at 15:49
  • Also, even if you are only interested in strings, you should still spend the time to come up with a better example. People who provide answers have a tendency to really tailor their solutions to address your *exact example*, and if you give a limited example, you will get limited answers. – John Y Mar 06 '14 at 15:51
  • Your new example is *entirely unclear* to me. I have no idea what you are trying to do there. – Martijn Pieters Mar 06 '14 at 16:02
  • Sorry, I get it have just edited the question to make it more formal – Antoine Gallix Mar 06 '14 at 16:03
  • You mean something like `result = next(a + foo + b for a, b in (s.split(),))`? Don't, that just gets to be unreadable. – Martijn Pieters Mar 06 '14 at 16:04

3 Answers3

5

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.

Community
  • 1
  • 1
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Ok I hadn't thought of this use of join, but I'm not asking here for a solution to my dummy problem, but if the list comprehension syntax that allows embedded loop and variable creations for creating lists, could be used to build not a full list, but a single object. – Antoine Gallix Mar 06 '14 at 15:49
  • @antoine: no, because list comprehensions only build lists. But you can combine that tool with lots of other tools in the python toolkit. – Martijn Pieters Mar 06 '14 at 15:50
  • @antoine: surely between list comprehensions, dict comprehensions, set comprehensions, generator expressions, `itertools`, `next()` and `iter()` you can find what you need for your tasks? – Martijn Pieters Mar 06 '14 at 15:51
1
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())
Community
  • 1
  • 1
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
1

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.

jme
  • 19,895
  • 6
  • 41
  • 39