207

Python does not warrant the use of semicolons to end statements.

So why is this (below) allowed?

import pdb; pdb.set_trace()
2
  • 5
    Note that such code is blatantly for debugging purposes only and would presumably be excised before it's "done". I use that snippet just as you have it so I can easily move it around. Commented Mar 3, 2015 at 4:10
  • Why was import used as the keyword for importing a module and not include? Why does Python use indentation for blocks instead of braces? The list is endless. It's just an arbitrary design choice. Commented Mar 31, 2024 at 18:35

15 Answers 15

290

Python does not require semicolons to terminate statements. Semicolons can be used to delimit statements if you wish to put multiple statements on the same line.

Now, why is this allowed? It's a simple design decision. I don't think Python needs this semicolon thing, but somebody thought it would be nice to have and added it to the language.

Sign up to request clarification or add additional context in comments.

7 Comments

It's useful for things like timeit a = 5; a*a
It seems useful for exec statements e.g. exec('for a in [1,2,3]:print a;print a+1')
I've come to Python with a background of C, Obj-C, Javascript, PHP. I frequently put a (useless) terminator ; at the end of a line. But fortunately Python forgives me
The semicolon is highly useful in the django shell, or the debugger, so you can write a small program on a single line and repeat it later.
@endolith What does timeit mean? a = 2; a*a is useless since a is still 2; it would have to be a = 2; a *= a
|
69

From 8. Compound statements:

Compound statements consist of one or more ‘clauses.’ A clause consists of a header and a ‘suite.’ The clause headers of a particular compound statement are all at the same indentation level. Each clause header begins with a uniquely identifying keyword and ends with a colon. A suite is a group of statements controlled by a clause. A suite can be one or more semicolon-separated simple statements on the same line as the header, following the header’s colon, or it can be one or more indented statements on subsequent lines. Only the latter form of suite can contain nested compound statements; the following is illegal, mostly because it wouldn’t be clear to which if clause a following else clause would belong:

if test1: if test2: print x

Also note that the semicolon binds tighter than the colon in this context, so that in the following example, either all or none of the print statements are executed:

if x < y < z: print x; print y; print z

Summarizing:

compound_stmt ::=  if_stmt
                   | while_stmt
                   | for_stmt
                   | try_stmt
                   | with_stmt
                   | funcdef
                   | classdef
                   | decorated
suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT
statement     ::=  stmt_list NEWLINE | compound_stmt
stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

4 Comments

Didn't know about the priority of semicolon being less than colon after an if. Thank's!
@gaborous I personally feel your comment ambiguous enough to make me thought you would mean the other way. So, to clarify, I would rather suggest other readers to stick with the official phrase: in that if cond: stmt1; stmt2; stmt3 example, either all or none of the statements are executed".
Yep that's what I meant, if the priority is lesser, then the lexer cannot leave the parent (colon) block until all semicolon statements are executed. That's really not an obvious thing.
Also in the referece for simple_stmt syntax, the documentation states: "... Several simple statements may occur on a single line separated by semicolons" docs.python.org/3/reference/compound_stmts.html
44

Python uses the ; as a separator, not a terminator. You can also use them at the end of a line, which makes them look like a statement terminator, but this is legal only because blank statements are legal in Python -- a line that contains a semicolon at the end is two statements, the second one blank.

3 Comments

If you put double semicolons at the end (or anywhere), you get a SyntaxError. So it seems blank statements are not entirely legal.
Probably it has the same logic as lists, tuples, dicts with trailing commas are valid and the same as their trimmed counterparts (e.g. [1,2,3]==[1,2,3,]) but they cannot contain double commas. So basically Python has a "trailing blank remover". Which by the way is clear from this: stmt_list ::= simple_stmt (";" simple_stmt)* [";"]
@Cucu You're right. You also can't start a line with a semicolon, or start an expression list with a comma. So it's more accurate to say that semicolons and commas are separators and optional terminators.
32

Semicolon in the interpreter

Having read the answers, I still miss one important aspect of using semicolons, possibly the only one where it really makes a difference...

When you're working in an interpreter REPL (the Python interactive shell, IDLE, and IPython) the value of the last expression is printed to the screen and usually this is the intended behavior.

Using an expression for side effects

But in some cases you want to evaluate an expression for its side effects only, e.g., to see the results of your simulation plotted by matplotlib.

In this cases you (probably) don't want to see the screenful of reprs of matplotlib objects that are sometimes returned by a call to a matplotlib function and, in IPython at least, one of the possibilities you have is to append a semicolon to the overly verbose statement, now IPython sees the input line as composed by two expressions, the matplotlib invocation and a null statement, so that the value of the compound expression is None and nothing is printed to the screen by the interpreter (the other possibility being assignment, as in _ = plot(...) but I find that a bit more intrusive).

Personal remark

IMHO, the use of the semicolon to suppress not desired output in the interpreter has become more relevant following the introduction of the IPython notebook, that permits to save the input and the output, including graphical output, of an interpreter session for documentation and eventual reuse.

4 Comments

I see, thank you for sharing! This just solved exactly my problem, where semicolon can prevent repr by matplotlib in ipython notebook
This is an IPython-only feature, and it's not a null statement, just a special syntax.
@wjandrea You're correct, it's just ipython... I have edited my answer to reflect your remark.
This answer should be higher, as I think it has become the most common use case (with the spread of the Jupyter notebook + IPython workflow)
13

As everyone else has noted, you can use semicolons to separate statements. You don't have to, and it's not the usual style.

As for why this is useful, some people like to put two or more really trivial short statements on a single line (personally I think this turns several trivial easily skimmed lines into one complex-looking line and makes it harder to see that it's trivial).

But it's almost a requirement when you're invoking Python one liners from the shell using python -c '<some python code>'. Here you can't use indentation to separate statements, so if your one-liner is really a two-liner, you'll need to use a semicolon. And if you want to use other arguments in your one-liner, you'll have to import sys to get at sys.argv, which requires a separate import statement. e.g.

python -c "import sys; print ' '.join(sorted(sys.argv[1:]))" 5 2 3 1 4
1 2 3 4 5

3 Comments

You can use indentation and newlines when passing commands through python in the shell: Just span your quoted code over multiple lines or use a heredoc. Still, that fails if you want it to be a "one-liner". ;)
includes traits for the rail answer with -c
More on one liners: "...which makes Python close to useless for command-line one-liner programs ... You can get away with a sequence of simple statements, separated by semi-colon ... as soon as you add a construct that introduces an indented block (like if), you need the line break"
10

I realize I am biased as an old C programmer, but there are times when the various Python conventions make things hard to follow. I find the indent convention a bit of an annoyance at times.

Sometimes, clarity of when a statement or block ends is very useful. Standard C code will often read something like this:

for(i=0; i<100; i++) {
    do something here;
    do another thing here;
}

continue doing things;

where you use the whitespace for a lot of clarity - and it is easy to see where the loop ends.

Python does let you terminate with an (optional) semicolon. As noted above, that does not mean that there is a statement to execute followed by a 'null' statement. SO, for example,

print(x);
print(y);

Is the same as

print(x)
print(y)

If you believe that the first one has a null statement at the end of each line, try - as suggested - doing this:

print(x);;

It will throw a syntax error.

Personally, I find the semicolon to make code more readable when you have lots of nesting and functions with many arguments and/or long-named arguments. So, to my eye, this is a lot clearer than other choices:

if some_boolean_is_true:
    call_function(
        long_named_arg_1,
        long_named_arg_2,
        long_named_arg_3,
        long_named_arg_4
    );

since, to me, it lets you know that last ')' ends some 'block' that ran over many lines.

I personally think there is much to much made of PEP style guidelines, IDEs that enforce them, and the belief there is 'only one Pythonic way to do things'. If you believe the latter, go look at how to format numbers: as of now, Python supports four different ways to do it.

I am sure I will be flamed by some diehards, but the compiler/interpreter doesn't care if the arguments have long or short names, and - but for the indentation convention in Python - doesn't care about whitespace. The biggest problem with code is giving clarity to another human (and even yourself after months of work) to understand what is going on, where things start and end, etc.

Comments

7

A quote from "When Pythons Attack"

Don't terminate all of your statements with a semicolon. It's technically legal to do this in Python, but is totally useless unless you're placing more than one statement on a single line (e.g., x=1; y=2; z=3).

3 Comments

Image
Why not x,y,z = 1,2,3?
@AnirbanNag'tintinmj' In this particular case, I believe x, y, z = 1, 2, 3 is slower because it incurs an unnecessary round trip of building a tuple and then immediately desembles it. (By the way, I don't really think @communistpancake is suggesting the x=1; y=2; z=3 pattern though. I think he/she is merely giving an example for how semicolon is a separator rather than a terminator.)
@AnirbanNag - because that would have been a rubbish example of a multi-statement line.
6

Semicolons are part of valid syntax: 8. Compound statements (The Python Language Reference)

Comments

5

Python does let you use a semicolon to denote the end of a statement if you are including more than one statement on a line.

Comments

4

Multiple statements on one line may include semicolons as separators. For example: 8. Compound statements. In your case, it makes for an easy insertion of a point to break into the debugger.

Also, as mentioned by Mark Lutz in the Learning Python Book, it is technically legal (although unnecessary and annoying) to terminate all your statements with semicolons.

Comments

3

Semicolon (";") is only needed for separation of statements within a same block, such as if we have the following C code:

if(a>b)
{
    largest = a;  // Here 'largest' and 'count' are integer variables
    count += 1;
}

It can be written in Python in either of the two forms:

if a > b:   
    largest = a
    count = count + 1

Or

if a > b:    largest = a; count = count + 1

In the above example, you could have any number of statements within an if block and can be separated by ";" instead.

I hope that nothing is as simple as the above explanation.

Comments

2

Semicolons (like dots, commas and parentheses) tend to cause religious wars. Still, they (or some similar symbol) are useful in any programming language for various reasons.

  • Practical: the ability to put several short commands that belong conceptually together on the same line. A program text that looks like a narrow snake has the opposite effect of what is intended by newlines and indentation, which is highlighting structure.

  • Conceptual: separation of concerns between pure syntax (in this case, for a sequence of commands) from presentation (e.g. newline), in the old days called "pretty-printing".

Observation: for highlighting structure, indentation could be augmented/replaced by vertical lines in the obvious way, serving as a "visual ruler" to see where an indentation begins and ends. Different colors (e.g. following the color code for resistors) may compensate for crowding.

Comments

2

It's allowed because authors decided to allow it: 6. Simple statements

If moving to the question why authors decided to do so, I guess it's so because semicolon is allowed as a simple statement termination at least in the following languages: C++, C, C#, R, MATLAB, and Perl.

So it's faster to move into usage of Python for people with background in other language. And there are no lose of generality in such decision.

Comments

2

Semicolons can be used to one line two or more commands. They don't have to be used, but they aren't restricted.

The semicolon ( ; ) allows multiple statements on the single line given that neither statement starts a new code block.

Python - Basic Syntax

1 Comment

This does not compute (is partly incomprehensible): "Semicolons can be used to one line two or more commands". Is a word missing? "one line" as a verb? It is not in the dictionary. Perhaps rephrase? (But without "Edit:", "Update:", or similar - the question/answer should appear as if it was written today.)
1

Related to the Matplotlib library:

import numpy as np
import matplotlib as plt

%matplotlib notebook
linear_data = np.array([1, 2, 3, 4, 5, 6, 7, 8])
quadratic_data = linear_data**2
plt.figure()
xvals = range(len(linear_data))
plt.barh(xvals, linear_data, height = 0.3, color='b')
plt.barh(xvals, quadratic_data, height = 0.3, left=linear_data, color='r')

If you don't provide a semicolon at the end of the barh (horizontal bar), the output is a plot + a function address. But if you use semicolons at the end of both barh lines, then it only shows the plot and suppresses the output for the function address.

Something like this: Comparison

4 Comments

This is specific to IPython, and doesn't apply to the standard Python REPL.
I think this is a brilliant example where the way the language writers thought they were introducing simplicity, power, and uniformity failed to think ahead to the problems just like this one.
Am I missing something because both graphs in that image look exactly the same
It displays a Barcontainer object after the displayed image which is irrelevant to the reader. So we might want to remove that. Except for that, obviously both the graphs are identical in each aspect. Hence the semicolon supressed the output.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.