<p>When coding in Python, I found that defining a list of strings without separating the strings with a comma is not a syntax error. When running this code:</p>
<pre class="lang-python prettyprint-override"><code>x = ['a', 'b', 'c'] # This is the proper one
y = ['a' 'b' 'c'] # Commas missing!
print(x) # results in ['a', 'b', 'c']
print(y) # results in ['abc']
</code></pre>
<p>However, if I run this code, Python complains about it.</p>
<pre class="lang-python prettyprint-override"><code>a = 'a'
b = 'b'
c = 'c'
z = [a b c] # SyntaxError: invalid syntax. Perhaps you forgot a comma?
</code></pre>
<p>Instead of reporting an error, Python simply assumes that the three non-comma-separated strings should be combined into the same string. What are the reasons for this? Is it common for people to write lists of strings without comma separators and intend for them to be the same string?</p>

<syntax><arrays><strings><python>
In Python, why isn't it a syntax error when a list of strings is defined without comma separators?
CC BY-SA 4.0
2023-08-06T04:06:23.190Z
[Relevant StackOverflow question](https://stackoverflow.com/q/18842779/9363594)
lyxal
CC BY-SA 4.0
2023-08-06T12:56:18.400Z
I provided input to the original ANSI X3J11 committee in the early 1980s, objecting to `"a" "b"` being treated like `"a" + "b"` rather than as a syntax error, as it would lead to undetectable typos and bugs. ¶ Over the years since then I've encountered more than a few instances of arrays of strings, one per line, being reordered leaving the string from the last line (no comma at the end) somewhere in the middle and silently concatenated to the following element. It's very difficult to notice (until things break weeks, months, or years later). I don't know why Python copied such a bad idea.
Ray Butterworth
CC BY-SA 4.0
2023-08-06T14:10:31.043Z
*"Is it common for people to write lists of strings without comma separators and intend for them to be the same string?"* Probably not lists, but individual strings, yes. And the syntax can't really have a different meaning just because it's in a list literal.
kaya3
CC BY-SA 4.0
2023-08-07T20:06:23.983Z
I’m voting to close this question because questions about programming in specific languages is more appropriate for [so].
Barmar
CC BY-SA 4.0
2023-08-07T20:52:48.753Z
@Barmar This question isn't about programming in Python, it's about a decision made by the designers of Python. Questions about the design or implementation of specific languages [are on-topic here](https://langdev.meta.stackexchange.com/q/96/89), and we have several other questions also tagged [tag:python].
kaya3
CC BY-SA 4.0
2023-08-07T21:01:25.820Z
@kaya3-supportthestrike I was reading the title, not the whole question, which is more like "Why is Python designed like this?" Although if you look at the meta question, they're saying that language-specific questions should just be examples of more general design questions. E.g. a better PLD question would be "What are the pros and cons of Python-like string literal concatenation?"
Barmar
CC BY-SA 4.0
2023-08-07T21:06:57.863Z
@Barmar Please don't vote to close questions after reading only the title. And nothing in the linked meta question or its answers say that questions like this should ask about hypothetical reasons instead of the actual language designers' rationale. The latter is more objective, even.
kaya3
CC BY-SA 4.0
2023-08-07T21:09:56.393Z
@kaya3-supportthestrike I understand, that's why I retracted my CV after your commengt.
Barmar
CC BY-SA 4.0
2023-08-07T21:10:40.883Z
@Barmar Ah, my apologies ─ I saw that the number of close-votes didn't change, but I guess someone else must have voted at the same time.
kaya3
CC BY-SA 4.0
2023-08-07T21:13:09.243Z
@kaya3-supportthestrike But I stand by my interpretation of the meta answer. Both examples they gave are trying to learn something general by asking about specifics.
Barmar
CC BY-SA 4.0
2023-08-08T18:44:43.550Z
@RayButterworth Unconditionally adding a trailing comma helps avoid array reordering-related bugs most of the time. Also, the alternative of having to join string literals with `+` is somewhat annoying because there cannot be a trailing `+` (nor a leading one, for strings), so reordering and other semi-automatic manipulations become a pain
abel1502
CC BY-SA 4.0
2023-08-08T21:08:56.480Z
@abel1502, agreed. But a mandatory "+" means that when you do it wrong, the compiler will notice and complain. ¶ Also, one trick is to start or end the list with a null string: `string = ""\n  +"aa"\n  +"bb"\n  +"cc"`.
Ray Butterworth
<p>The reason the first example does not error is because Python will <a href="https://docs.python.org/3/reference/lexical_analysis.html#string-literal-concatenation" rel="noreferrer">automatically concatenate adjacent string literals</a>. This happens inside and outside of lists.</p>
<p>As mentioned in the Python documentation, this:</p>
<blockquote>
<p>can be used to reduce the number of backslashes needed, to split long strings conveniently across long lines, or even to add comments to parts of strings[.]</p>
</blockquote>
<p>This feature was once <a href="https://peps.python.org/pep-3126/" rel="noreferrer">considered for removal</a>, however, &quot;[t]here wasn’t enough support in favor, the feature to be removed isn’t all that harmful, and there are some use cases that would become harder.&quot;</p>
<p>As to why implicit string concatenation exists:</p>
<blockquote>
<p>Many Python parsing rules are intentionally compatible with C. This is a useful default, but Special Cases need to be justified based on their utility in Python. ...</p>
<p>In C, implicit concatenation is the only way to join strings without using a (run-time) function call to store into a variable.</p>
</blockquote>
<p><a href="https://peps.python.org/pep-3126/#history-or-future" rel="noreferrer">source</a></p>

CC BY-SA 4.0
2023-08-06T04:05:50.553Z
2023-08-06T04:05:50.553Z
lyxal
CC BY-SA 4.0
2024-06-26T22:36:19.947Z
@Barmar: In C, this has the benefit that tokens never span multiple lines, so a tokeniser can report lexical errors per line, and always recover at a line break. To my knowledge, Python has always had multiline string tokens, so it doesn’t make use of this. But overall it helps with error reporting to prevent runaway syntax.
Jon Purdy
CC BY-SA 4.0
2024-07-05T22:00:34.147Z
@JonPurdy Python has had multiline string tokens (triple-quoted strings) for at least a very long time, but indenting them is tricky because they incorporate any whitespace you might use to indent the noninitial lines. A series of juxtaposed single-line string literals (especially inside brackets to make use of implicit line joining) is a way to avoid that.
chepner
CC BY-SA 4.0
2024-07-07T02:32:07.143Z
@chepner: Sure, they’re both useful and all. I just meant Python is missing out on one of the benefits of this syntax because it doesn’t have the C feature that newlines are recovery points when you don’t have multiline tokens, because it *does* have them—and has for a long time, so evidently it was never a goal to be lexically compatible with C, just to be somewhat familiar-looking to C users.
Jon Purdy
CC BY-SA 4.0
2023-08-07T20:09:30.690Z
C needs this feature so that concatenation can be done in macro expansions or with macros that expand into string literals. That need doesn't exist in Python, so this really does seem like an unnecessary compatibility.
Barmar
# In Python, why isn't it a syntax error when a list of strings is defined without comma separators?
Posted by: username_0 on 2023-08-06
When coding in Python, I found that defining a list of strings without separating the strings with a comma is not a syntax error. When running this code:
x = ['a', 'b', 'c'] # This is the proper one
y = ['a' 'b' 'c'] # Commas missing!
print(x) # results in ['a', 'b', 'c']
print(y) # results in ['abc']

However, if I run this code, Python complains about it.
a = 'a'
b = 'b'
c = 'c'
z = [a b c] # SyntaxError: invalid syntax. Perhaps you forgot a comma?

Instead of reporting an error, Python simply assumes that the three non-comma-separated strings should be combined into the same string. What are the reasons for this? Is it common for people to write lists of strings without comma separators and intend for them to be the same string?
**Tags:** syntax arrays strings python
> **Comments:**
> **username_1**: [Relevant StackOverflow question](https://stackoverflow.com/q/18842779/9363594)  
> **username_2**: I provided input to the original ANSI X3J11 committee in the early 1980s, objecting to `"a" "b"` being treated like `"a" + "b"` rather than as a syntax error, as it would lead to undetectable typos and bugs. ¶ Over the years since then I've encountered more than a few instances of arrays of strings, one per line, being reordered leaving the string from the last line (no comma at the end) somewhere in the middle and silently concatenated to the following element. It's very difficult to notice (until things break weeks, months, or years later). I don't know why Python copied such a bad idea.  
> **username_3**: *"Is it common for people to write lists of strings without comma separators and intend for them to be the same string?"* Probably not lists, but individual strings, yes. And the syntax can't really have a different meaning just because it's in a list literal.  
> **username_4**: I’m voting to close this question because questions about programming in specific languages is more appropriate for [so].  
> **username_3**: @Barmar This question isn't about programming in Python, it's about a decision made by the designers of Python. Questions about the design or implementation of specific languages [are on-topic here](https://langdev.meta.stackexchange.com/q/96/89), and we have several other questions also tagged [tag:python].  
> **username_4**: @kaya3-supportthestrike I was reading the title, not the whole question, which is more like "Why is Python designed like this?" Although if you look at the meta question, they're saying that language-specific questions should just be examples of more general design questions. E.g. a better PLD question would be "What are the pros and cons of Python-like string literal concatenation?"  
> **username_3**: @Barmar Please don't vote to close questions after reading only the title. And nothing in the linked meta question or its answers say that questions like this should ask about hypothetical reasons instead of the actual language designers' rationale. The latter is more objective, even.  
> **username_4**: @kaya3-supportthestrike I understand, that's why I retracted my CV after your commengt.  
> **username_3**: @Barmar Ah, my apologies ─ I saw that the number of close-votes didn't change, but I guess someone else must have voted at the same time.  
> **username_4**: @kaya3-supportthestrike But I stand by my interpretation of the meta answer. Both examples they gave are trying to learn something general by asking about specifics.  
> **username_5**: @RayButterworth Unconditionally adding a trailing comma helps avoid array reordering-related bugs most of the time. Also, the alternative of having to join string literals with `+` is somewhat annoying because there cannot be a trailing `+` (nor a leading one, for strings), so reordering and other semi-automatic manipulations become a pain  
> **username_2**: @abel1502, agreed. But a mandatory "+" means that when you do it wrong, the compiler will notice and complain. ¶ Also, one trick is to start or end the list with a null string: `string = ""\n  +"aa"\n  +"bb"\n  +"cc"`.  
---
## 1 answers
### Answer by username_1 on 2023-08-06. Score: 24 | Accepted answer
The reason the first example does not error is because Python will [automatically concatenate adjacent string literals](https://docs.python.org/3/reference/lexical_analysis.html#string-literal-concatenation). This happens inside and outside of lists.

As mentioned in the Python documentation, this:

> can be used to reduce the number of backslashes needed, to split long strings conveniently across long lines, or even to add comments to parts of strings[.]

This feature was once [considered for removal](https://peps.python.org/pep-3126/), however, "[t]here wasn’t enough support in favor, the feature to be removed isn’t all that harmful, and there are some use cases that would become harder."

As to why implicit string concatenation exists:

> Many Python parsing rules are intentionally compatible with C. This is a useful default, but Special Cases need to be justified based on their utility in Python. ...
>
> In C, implicit concatenation is the only way to join strings without using a (run-time) function call to store into a variable.

[source](https://peps.python.org/pep-3126/#history-or-future)
> **Comments:**
> **username_4** (2023-08-07): C needs this feature so that concatenation can be done in macro expansions or with macros that expand into string literals. That need doesn't exist in Python, so this really does seem like an unnecessary compatibility.  
> **username_6** (2024-06-26): @Barmar: In C, this has the benefit that tokens never span multiple lines, so a tokeniser can report lexical errors per line, and always recover at a line break. To my knowledge, Python has always had multiline string tokens, so it doesn’t make use of this. But overall it helps with error reporting to prevent runaway syntax.  
> **username_7** (2024-07-05): @JonPurdy Python has had multiline string tokens (triple-quoted strings) for at least a very long time, but indenting them is tricky because they incorporate any whitespace you might use to indent the noninitial lines. A series of juxtaposed single-line string literals (especially inside brackets to make use of implicit line joining) is a way to avoid that.  
> **username_6** (2024-07-07): @chepner: Sure, they’re both useful and all. I just meant Python is missing out on one of the benefits of this syntax because it doesn’t have the C feature that newlines are recovery points when you don’t have multiline tokens, because it *does* have them—and has for a long time, so evidently it was never a goal to be lexically compatible with C, just to be somewhat familiar-looking to C users.  
---
