LanguageSyntax

Comments

# Single-line comment
x = 1  # Trailing comment
 
"""
Triple-quoted strings used as
module-level documentation are
parsed but discarded.
"""

Identifiers and assignment

Identifiers follow Python rules: letters, digits, underscores, plus any non-ASCII letter.

counter = 0
café = "open"
π = 3.14159
 
# Multiple targets
a = b = c = 0
print(a, b, c)
0 0 0

Tuple unpacking

a, b = 1, 2
print(a, b)
 
# Star pattern
first, *middle, last = [1, 2, 3, 4, 5]
print(first, middle, last)
1 2
1 [2, 3, 4] 5

Walrus operator

Assignment as expression. Useful in conditions and comprehensions.

data = [1, 2, 3]
if (n := len(data)) > 0:
    print(n)
3

Numbers

Integer literals: hex (0x), octal (0o), binary (0b); _ digit separators between digits. Range and promotion: Data types, Integer.

print(0xDEAD_BEEF)
print(0o777)
print(0b1010_1010)
print(1_000_000)
3735928559
511
170
1000000

Underscores are validated, 1_, 1__2, 0x_1, 1e_5 -> SyntaxError. Must sit between two digits.

# Floats: IEEE-754 doubles
print(3.14)
print(1e-5)
print(.5)
 
# Mixed arithmetic coerces to float
print(2 + 3.0)
3.14
0.00001
0.5
5.0

Complex literals (1j, 2+3j) are not part of the language.

Strings

print('single')
print("double")
print("""triple
quoted""")
print(r'raw\n') # backslash not escaped
print('hello' ' world') # implicit concatenation
single
double
triple
quoted
raw\n
hello world

Escape sequences

Supported: \n, \t, \r, \\, \', \", \0, \xHH, \uHHHH, \UHHHHHHHH, \NNN (1\u20133 octal digits). Named-char escapes (\N{GREEK SMALL LETTER ALPHA}) not supported \u2014 use \u.

print('\n line break')
print('\t tab')
print('\x41 hex')
print('\u00e9 unicode')
print('\101') # octal escape \u2014 'A'

 line break
	 tab
A hex
\u00e9 unicode
A

f-strings

name = "world"
n = 42
pi = 3.14159
print(f"hello {name}")
print(f"answer is {n + 1}")
print(f"{n:04d}") # zero-padded width
print(f"{pi:.3f}") # float precision
print(f"{255:#x}") # hex with prefix
print(f"{name!r}") # !r conversion
print(f"{{literal braces}}")
hello world
answer is 43
0042
3.142
0xff
'world'
{literal braces}

Full format mini-language: [[fill]align][sign][#][0][width][,][.precision][type], with !r / !s / !a conversions before the spec. Type chars: b o c d e E f F g G n s x X %.

Booleans and None

print(True, False, None)
print(bool(0), bool(1), bool(""), bool("x"))
print(not True)
True False None
False True False True
False

Operators

Arithmetic

print(7 + 3, 7 - 3, 7 * 3, 7 / 3)
print(7 // 3, 7 % 3, 2 ** 10)
print(-5, +5)
10 4 21 2.3333333333333335
2 1 1024
-5 5

Comparison and chaining

print(1 < 2 < 3) # chained
print(0 < 5 < 10)
print(1 == 1 == 1)
True
True
True

Logical

Short-circuiting and / or return the operand, not a coerced bool:

print(True and "second")
print(0 or "fallback")
print(None or 0 or [] or "default")
second
fallback
default

Bitwise

print(5 & 3, 5 | 3, 5 ^ 3, ~5)
print(1 << 4, 32 >> 2)
1 7 6 -6
16 8

Membership and identity

print(2 in [1, 2, 3])
print('a' in {'a': 1})
print(None is None)
print(1 is not 2)
True
True
True
True

Augmented assignment

+= -= *= /= //= %= **= &= |= ^= <<= >>=

x = 10
x += 5
x *= 2
print(x)
30

Conditional expression

x = 5
print("big" if x > 3 else "small")
big

Containers

Literals: [1, 2, 3] (list), (1, 2, 3) / (1,) / () (tuple), {"a": 1} (dict), {1, 2, 3} (set, empty is set() since {} is a dict). See Data types for semantics, mutation, methods.

Slicing

a = [1, 2, 3, 4, 5]
print(a[1:4]) # [start:stop]
print(a[:2])
print(a[3:])
print(a[::2]) # every 2nd
print(a[::-1]) # reversed
[2, 3, 4]
[1, 2]
[4, 5]
[1, 3, 5]
[5, 4, 3, 2, 1]

Comprehensions

print([x * x for x in range(5)])
print([x for x in range(10) if x % 2 == 0])
print([(i, j) for i in range(2) for j in range(2)])
print({x: x * x for x in range(4)})
print({x % 3 for x in range(10)})
[0, 1, 4, 9, 16]
[0, 2, 4, 6, 8]
[(0, 0), (0, 1), (1, 0), (1, 1)]
{0: 0, 1: 1, 2: 4, 3: 9}
{1, 2, 0}

Generator expressions consumed by reducers:

print(sum(x * x for x in range(5)))
print(max(x for x in [3, 1, 4, 1, 5]))
30
5

Type annotations

Annotations parse on variables, parameters, and return positions but have no runtime effect, drained by the parser, never reach the VM. No __annotations__, no runtime check. Treat them as docs for humans and static analysers.

counter: int = 0
name: str = "edge"
 
def add(a: int, b: int) -> int:
    return a + b
 
print(add(3, 4))
print(add("a", "b")) # annotations don't enforce: int+str logic decides
7
ab