String concatenation without '+' operator

90,506

Solution 1

From the docs:

Multiple adjacent string literals (delimited by whitespace), possibly using different quoting conventions, are allowed, and their meaning is the same as their concatenation. Thus, "hello" 'world' is equivalent to "helloworld".


Statement 3 doesn't work because:

The ‘+’ operator must be used to concatenate string expressions at run time.

Notice that the title of the subheader in the docs is "string literal concatenation" too. This only works for string literals, not other objects.


There's probably no difference. If there is, it's probably extremely tiny and nothing that anyone should worry about.


Also, understand that there can be dangers to this:

>>> def foo(bar, baz=None):
...     return bar
... 
>>> foo("bob"
... "bill")
'bobbill'

This is a perfect example of where Errors should never pass silently. What if I wanted "bill" to be the argument baz? I have forgotton a comma, but no error is raised. Instead, concatenation has taken place.

Solution 2

You can use %s as this is more efficient than using + sign.

>>> string2 = "%s %s" %('Hello', 'World')
>>> string2
'Hello World'

(OR)


one more method is .format

>>> string2 = "{0} {1}".format("Hello", "World")
>>> string2
'Hello World'
>>> 

Solution 3

This is implicit string literal concatenation. It only happens with string literals, not variables or other expressions that evaluate to strings. There used to be a (tiny) performance difference, but these days, the peephole optimizer should render the forms essentially equivalent.

Solution 4

To answer your second question: There is no difference at all (at least with the implementation I use). Disassembling both statements, they are rendered as LOAD_CONST STORE_FAST. They are equivalent.

Solution 5

Statement 3 doesn't work as when you concatenate two string expressions to create a new string you need a '+' operator.

whereas in case of sting 1,2 and 4, adjacent literals separated by white spaces use different quoting conventions.Hence they are allowed making them print same as their concatenation.

also, there won't be any significant or noticeable time difference in running those 2 operations.

%%timeit -n 1
s1='ab'
s2='ba'
print(s1+s2)

o/p The slowest run took 17.08 times longer than the fastest. This could mean that an intermediate result is being cached. 57.8 µs ± 92.5 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

%%timeit -n 1
s3='ab' 'ba'
print(s3)

o/p The slowest run took 4.86 times longer than the fastest. This could mean that an intermediate result is being cached. 25.7 µs ± 21 µs per loop (mean ± std. dev. of 7 runs, 1 loop each)

Share:
90,506
ibrahim
Author by

ibrahim

Updated on July 05, 2022

Comments

  • ibrahim
    ibrahim almost 2 years

    I was playing with python and I realized we don't need to use '+' operator to concatenate static strings. But it fails if I assign it to a variable.

    For example:

    string1 = 'Hello'   'World'  #1 works fine
    string2 = 'Hello' + 'World'  #2 also works fine
    
    string3 = 'Hello'
    string4 = 'World'
    string5 = string3   string4  #3 causes syntax error
    string6 = string3 + string4  #4 works fine
    

    Now I have two questions:

    1. Why statement 3 does not work while statement 1 does?
    2. Is there any technical difference such as calculation speed etc. between statement 1 and 2?
  • flornquake
    flornquake over 10 years
    That is the case in CPython, but afaik not in every implementation.
  • Steve Jessop
    Steve Jessop over 10 years
    So "Errors should never pass silently" in this case means that the grammar should be defined such that if a comma is removed from any valid program, the resulting program is either invalid or else has the same meaning as the original program? I mean syntactically significant comma, ofc, the rule shouldn't apply to removing a comma from inside a string literal ;-)
  • TerryA
    TerryA over 10 years
    @SteveJessop Hmm, I guess it doesn't suit this example, doesn't it. Because technically there is no error, right?
  • Steve Jessop
    Steve Jessop over 10 years
    Well, as a language designer if you think "leaving out a comma" is a common typo, then it's reasonable to decide that you will not create situations where leaving out a comma changes a valid program to another valid program with different meaning. Your example code is an error if the programmer intended a comma and not if the programmer didn't, the issue is that the language is defined such that the interpreter can't tell which. There are other cases in Python where that happens, for example (0) != (0,), and each one has its reasons that GvR considered more important.
  • TerryA
    TerryA over 10 years
    @SteveJessop Ah, I get you. Should I change my answer to something else? Perhaps just remove the sentence?
  • Steve Jessop
    Steve Jessop over 10 years
    I think your answer is interesting with the sentence. I suppose that someone who takes it as a criticism of the design of Python might come back harshly on it, and/or consider it subjective. But it's true that this can be a gotcha, so Python users need to be aware of it and recognise the symptoms when it happens. The same applies in C and C++.
  • Steve Jessop
    Steve Jessop over 10 years
    Another example applying to both Python and C (even though the comma doesn't mean the same thing): 1 - 1 and 1 , - 1 are different. Basically, context-sensitive operators lead to such examples, and juxtaposition in effect turns token boundaries into context-sensitive operators. String concatenation is a particularly easy mistake to make since it's pretty common to introduce linebreaks into comma-separated lists of strings. If you wrote foo(1, <newline> -1) then you'd have in effect the same lack of ability of the language to tell when you leave off the trailing comma.
  • TerryA
    TerryA over 10 years
    @SteveJessop Wow, that's amazing. I've attempted to learn C++ before, but I never got into it because I love python (especially its syntax) so much, but you have definitely taught me a lot here. Thank you!
  • Hyperboreus
    Hyperboreus over 10 years
    @flornquake Thank you for your input. I updated and somewhat restricted my answer.
  • sheridp
    sheridp over 7 years
    This is a terrible "feature" of python. My program just silently failed because I missed a comma when typing out the long list of names for a pandas header.
  • AJP
    AJP almost 7 years
    Interestingly in 2.7 and 3.6 it appears that "delimited by whitespace" is not needed as both "a""b" and "a"'b' work fine to give "ab". It's interesting GvR chose to copy this behaviour from C etc. as it's only a single + character to make it explicit.
  • chepner
    chepner about 4 years
    It's a single character, but it would require the parser to make semantic decisions (e.g., "a" + "b" == "ab", but "a" - "b" is a runtime error). Juxtaposition can be handled easily by the parser itself, by merging two tokens lexically.