A terse reference with comparisons to JS
# No semicolons, no braces. Blocks defined by colon + indentation.
if x > 0:
print(x)- JS:
{}blocks,; - Python: indentation IS the block.
snake_case_var = 10
CONSTANT_VALUE = 3.14
_private_by_convention = None- JS:
camelCase,UPPER_SNAKEfor consts. - Python:
snake_caseeverywhere; novar/let/constkeyword — justname = value.
if x > 0:
result = "pos"
elif x == 0:
result = "zero"
else:
result = "neg"
# match/case (3.10+) = switch equivalent
match status:
case 200:
pass
case 404 | 500:
pass
case _:
pass
# ternary
y = "yes" if x else "no"- JS:
else if,switch/casewithbreakrequired - Python
matchhas no fallthrough - JS ternary:
x ? "yes" : "no".
for i in range(5):
print(i)
for item in my_list:
print(item)
while x < 10:
x += 1- JS:
for(let i=0;i<5;i++),for...of,while. - No C-style for-loop in Python —
range()instead. - No
++/--in Python.
arr = [1, 2, 3]
arr.append(4)
arr[0] # 1
arr[-1] # last element
arr[1:3] # slice- JS:
push()notappend(). - Python has negative indexing and slicing natively;
- JS needs
.slice().
- JS needs
obj = {"key": "value", "n": 1}
obj["key"]
obj.get("missing", "default")
for k, v in obj.items():
print(k, v)- JS:
obj.keyorobj["key"]; - Python only
obj["key"](no dot access on dict)..items()vsObject.entries().
class Dog:
def __init__(self, name):
self.name = name
def bark(self):
return f"{self.name} says woof"
d = Dog("Rex")- JS:
constructor(),this. - Python:
__init__, explicitselfas first param of every method- JS
thisis implicit
- JS
# concatenation
s = "a" + "b"
s += "c"
# f-strings (3.6+) — variables inside strings
name = "Rex"
msg = f"Hello {name}, {2+2} more"
# .format() alt
msg = "Hello {}".format(name)
# escapes
s = "line1\nline2\ttab\\backslash\"quote"
raw = r"C:\no\escapes" # raw string, backslashes literal
# regex
import re
re.search(r"\d+", "abc123") # match object or None
re.findall(r"\d+", "a1 b22") # ['1', '22']
re.sub(r"\s+", "_", "a b c") # 'a_b_c'- JS: template literals
`Hello ${name}`vs - Python f-strings
f"Hello {name}". - JS regex is a literal
/\d+/; - Python regex is a string passed to
remodule, no native regex literal syntax.
def add(a, b=10, *args, **kwargs):
return a + b
add(1) # positional, b defaults to 10
add(1, b=5) # keyword arg
add(1, 2, 3, 4) # *args collects extras -> (3, 4)
square = lambda x: x * x # anonymous function- JS:
function add(a, b=10) {}or arrow(a,b=10)=>a+b; no*args/**kwargs— JS uses...rest. - Python
lambdais single-expression only (no{}body).
def outer():
x = 1
def inner():
nonlocal x # needed to REASSIGN outer's x (not just read)
x += 1
inner()
return x- JS: closures read/write outer vars freely, no
nonlocalkeyword needed. - Python requires
nonlocal(orglobal) to assign — without it,xis read fine but assignment creates a new local.
x = 5 # int
x = 5.0 # float
x = "s" # str
x = True # bool
x = None # NoneType (JS: null/undefined)
x = [1,2] # list
x = (1,2) # tuple (immutable)
x = {1,2} # set
x = {"a":1} # dict
# scope
g = 10
def f():
global g
g += 1 # without 'global', this creates a local var instead- JS: dynamic typing too, but
var(function-scoped) vslet/const(block-scoped); - Python has no block scope — only function/module scope, and
if/forblocks don't create new scopes. - Python: no separate int/float declaration keywords; type inferred at assignment.
import math
math.sqrt(4)
from math import sqrt
sqrt(4)
import numpy as np
np.array([1,2,3])
from mypackage.module import MyClass- JS:
import { sqrt } from 'math'(ESM) orrequire('math')(CommonJS). - Python:
pip install <pkg>to fetch (vsnpm install); no bundler needed at runtime.
# single line
"""
multi-line
(technically a string, used as docstring/comment)
"""- JS:
//and/* */. - Python has no true multi-line comment syntax — triple-quoted strings are the convention.
Gist Version 1.0
Copyright © 2026 Andrew Somers. All Rights Reserved.