199

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

So why is this (below) allowed?

import pdb; pdb.set_trace()
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
canadadry
  • 8,115
  • 12
  • 51
  • 68
  • 3
    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. – Nick T Mar 03 '15 at 04:10
  • Lol I came to this question from the same website: https://realpython.com/python-debugging-pdb/ – mackycheese21 Apr 23 '19 at 00:29

15 Answers15

276

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
André Caron
  • 44,541
  • 12
  • 67
  • 125
  • 21
    It's useful for things like ``timeit a = 5; a*a`` – endolith May 23 '13 at 19:00
  • 16
    It seems useful for exec statements e.g. exec('for a in [1,2,3]:print a;print a+1') – Phil C Jun 30 '13 at 08:28
  • 90
    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 – Paolo Sep 28 '13 at 13:31
  • 40
    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. – Bryce Oct 02 '13 at 05:48
  • 9
    @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` – Nearoo May 10 '17 at 02:02
  • 4
    The [semicolon is nice to have in the REPL](https://stackoverflow.com/a/29094034/2749397) if you evaluate an expression for its side-effects and are not interested in what the expression returns (typical example, `matplotlib.pyplot` methods). – gboffi Sep 12 '17 at 09:01
  • 2
    Semicolons are super useful for me when I have to run a short script from command line without a script file. It's easier to type many expressions separated with semicolon (`python -c "import time;t = time.time();print(int(t))"`) than do the same thing with new line character. – itachi May 24 '19 at 14:26
67

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)* [";"]
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
chown
  • 51,908
  • 16
  • 134
  • 170
  • 5
    Didn't know about the priority of semicolon being less than colon after an if. Thank's! – gaborous Oct 13 '14 at 22:54
  • 3
    @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".** – RayLuo Sep 30 '16 at 21:00
  • 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. – gaborous Oct 02 '16 at 11:50
43

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.

kindall
  • 178,883
  • 35
  • 278
  • 309
  • 31
    If you put double semicolons at the end (or anywhere), you get a SyntaxError. So it seems blank statements are not entirely legal. – Andras Nemeth Apr 18 '13 at 11:07
  • 12
    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)* [";"]` – Andras Nemeth Apr 19 '13 at 14:14
  • 1
    @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. – wjandrea Jun 02 '20 at 15:12
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
gboffi
  • 22,939
  • 8
  • 54
  • 85
  • I see, thank you for sharing! This just solved exactly my problem, where semicolon can prevent repr by matplotlib in ipython notebook – Napitupulu Jon Mar 17 '15 at 09:12
  • This is an IPython-only feature, and it's not a null statement, just a special syntax. – wjandrea Jun 02 '20 at 15:21
  • @wjandrea You're correct, it's just `ipython`... I have edited my answer to reflect your remark. – gboffi Jun 03 '20 at 12:32
  • 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) – Josh Friedlander Jul 22 '20 at 16:21
12

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
Ben
  • 68,572
  • 20
  • 126
  • 174
  • 2
    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". ;) – 00dani Jan 30 '14 at 01:26
  • includes traits for the rail answer with `-c` – n611x007 Jul 06 '15 at 12:24
  • 1
    [More on one liners](https://stackoverflow.com/questions/6167127/how-to-put-multiple-statements-in-one-line/6167353#6167353): *"...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"* – Peter Mortensen Apr 27 '22 at 09:36
9

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
eSurfsnake
  • 647
  • 6
  • 17
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).

CommunistPancake
  • 597
  • 2
  • 10
  • 22
  • 6
    Why not `x,y,z = 1,2,3`? – Anirban Nag 'tintinmj' Feb 17 '14 at 19:48
  • 7
    @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.) – RayLuo Sep 30 '16 at 21:12
  • 4
    @AnirbanNag - because that would have been a rubbish example of a multi-statement line. – c z Mar 02 '18 at 12:11
6

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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Dmitry B.
  • 9,107
  • 3
  • 43
  • 64
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Godwin
  • 9,739
  • 6
  • 40
  • 58
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
mandarg
  • 41
  • 1
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.

Raymond
  • 21
  • 1
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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Konstantin Burlachenko
  • 5,233
  • 2
  • 41
  • 40
2

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.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Mohd Asim
  • 724
  • 9
  • 7
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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
craniumonempty
  • 3,525
  • 2
  • 20
  • 18
  • 1
    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](https://stackoverflow.com/posts/8236412/edit)? (But ***without*** "Edit:", "Update:", or similar - the question/answer should appear as if it was written today.) – Peter Mortensen Apr 27 '22 at 08:53
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

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Farhan Hai Khan
  • 583
  • 7
  • 10
  • 4
    This is specific to IPython, and doesn't apply to the standard Python REPL. – wjandrea Jun 02 '20 at 15:25
  • 1
    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. – eSurfsnake Jul 16 '20 at 02:50
  • Am I missing something because both graphs in that image look exactly the same – Break Sep 16 '20 at 23:44
  • 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. – Farhan Hai Khan Sep 18 '20 at 05:43