Python for Swift Devs

The complete reference — every Swift concept mapped to Python with tips, gotchas & real-world patterns

Swift / iOSPython 3.10+21 Sections
21
Sections
150+
Examples
50+
Tips

01 The Basics — Syntax Philosophy

🍎 Swift
// single-line comment
/* multi-line comment */
print("Hello, World!")
// braces { } define blocks
🐍 Python
# single-line comment
""" multi-line comment """
print("Hello, World!")
# INDENTATION defines blocks
⚡ The #1 Rule — Indentation IS Your Braces Python uses 4 spaces (not tabs!) for code blocks. The colon : + indent replaces { }. Get this wrong and nothing runs.

Running Python — Your "Build & Run"

# Terminal (like running a playground)
python3 script.py

# Interactive REPL (like Swift REPL)
python3
>>> print("Hello")
>>> exit()

# Jupyter Notebook (like Xcode Playgrounds but better)
pip install jupyter
jupyter notebook

The Entry Point — if __name__

# In Swift you have @main or AppDelegate
# In Python:

def main():
    print("App started")

if __name__ == "__main__":
    main()

# Runs main() only when you execute THIS file directly,
# not when another file imports it.
💡 iOS Dev Tip — Python Philosophy Type import this in the REPL to see "The Zen of Python." Key idea: "There should be one obvious way to do it." Python prefers one clear way unlike Swift's multiple approaches.

print() Options

print("a", "b", "c")          # a b c
print("a", "b", sep="-")       # a-b
print("no newline", end="")    # no \n
print(f"x = {42}")             # x = 42

Input from User

# Like readLine() in Swift
name = input("Your name: ")
age = int(input("Age: "))
# input() always returns str!

02 Variables & Constants

🍎 Swift
var name: String = "Ali"
let age: Int = 25
let PI = 3.14    // truly immutable
🐍 Python
name = "Ali"
AGE = 25          # convention only!
PI = 3.14         # nothing enforces it
⚡ No let vs var Python has NO immutability keyword. UPPERCASE is just a "please don't change this" convention.

Type Hints OPTIONAL

name: str = "Ali"
age: int = 25
scores: list[int] = [90, 85]
maybe: str | None = None   # like String?

from typing import Optional
name: Optional[str] = None  # same as str | None

Multiple Assignment & Naming

x, y, z = 1, 2, 3       # multi assign
a, b = b, a              # swap — no temp!
a = b = c = 0            # same value

# Swift: camelCase → Python: snake_case
my_variable = 10         # variables
MY_CONSTANT = 3.14       # constants
def my_function(): ...    # functions
class MyClass: ...        # classes: PascalCase
_private_var = 5          # _ prefix = "private"
🚨 Gotcha — Mutable Default Trap def add(item, lst=[]): ← The [] is shared across ALL calls!
def add(item, lst=None): ← Do this instead, then lst = lst or [] inside.

03 Data Types — Complete Map

PythonSwiftNotes
intIntUnlimited precision! No overflow
floatDoubleAlways 64-bit
complexz = 3+4j
strStringImmutable, Unicode
boolBoolTrue/False capital!
bytesDatab"hello"
list[Any]Mutable, ordered
tuple(Int, String)Immutable
dict[String: Any]Key-value, ordered (3.7+)
setSet<Int>Unique unordered
frozensetImmutable set
NonenilThe null value
💡 No Integer Overflow! 2 ** 1000 just works in Python. No Int.max, no overflow. Great for algorithms.

Type Checking & Casting

type(x)                 # <class 'int'>
isinstance(x, int)      # True — like "x is Int"
isinstance(x, (int, float))  # check multiple

int("42")    float("3.14")    str(42)
bool(0)      list("abc")      set([1,1,2])

Number Operations

10 / 3      # 3.333... (always float!)
10 // 3     # 3        (floor division)
10 % 3      # 1        (modulo)
2 ** 10     # 1024     (power)
abs(-5)     # 5
round(3.7)  # 4
divmod(10,3)# (3, 1)
🚨 Gotcha — Division Swift: 10 / 3 = 3. Python: 10 / 3 = 3.333.... Use // for integer division!

04 Strings — Deep Dive

🍎 Swift
let name = "Ali"
"Hello \(name)"
name.count
name.uppercased()
name.contains("A")
name.hasPrefix("A")
name.hasSuffix("i")
🐍 Python
name = "Ali"
f"Hello {name}"
len(name)
name.upper()
"A" in name
name.startswith("A")
name.endswith("i")

All String Methods You Need

s = "  Hello, World!  "

# Case
s.upper()  s.lower()  s.title()  s.capitalize()  s.swapcase()

# Trim
s.strip()     # both sides  → .trimmingCharacters
s.lstrip()    # left only
s.rstrip()    # right only

# Search
s.find("World")   # 9 or -1
s.index("World")  # 9 or raises error
s.count("l")      # 3

# Modify
s.replace("World", "Python")
s.split(",")
"-".join(["a","b","c"])  # "a-b-c"

# Check
"123".isdigit()   "abc".isalpha()   "  ".isspace()

String Slicing ⭐ YOU'LL LOVE THIS

s = "Hello World"
s[0]       # "H"        first char
s[-1]      # "d"        last char
s[0:5]     # "Hello"    slice
s[6:]      # "World"    from index 6
s[:5]      # "Hello"    first 5
s[::-1]    # "dlroW olleH" REVERSED!
s[::2]     # "HloWrd"   every 2nd
💡 Goodbye String.Index! Python's s[0:5] just works with integers. No more string.index(string.startIndex, offsetBy:) madness.

f-Strings — Advanced Formatting

f"Hi {name}!"                  # basic
f"Total: ${price:.2f}"         # "Total: $49.99"
f"Users: {count:,}"            # "Users: 1,000,000"
f"{'Ali':>10}"                 # "       Ali" right-align
f"{'Ali':^10}"                 # "   Ali    " center
f"Bin: {255:08b}"             # "11111111"
f"Hex: {255:#x}"              # "0xff"
f"Pct: {0.856:.1%}"          # "85.6%"
f"Debug: {name!r}"             # "'Ali'" (repr)

# Raw string (great for regex / paths)
path = r"C:\Users\name\file"

# Multi-line f-string
html = f"""
<h1>{name}</h1>
<p>Age: {age}</p>
"""

05 Collections — Lists, Dicts, Sets & More

Lists → Swift Arrays EASY

nums = [1, 2, 3, 4, 5]
repeated = [0] * 10         # Array(repeating:count:)

# Add
nums.append(6)               # add one
nums.extend([7, 8])          # add many → .append(contentsOf:)
nums.insert(0, 99)           # insert at index

# Remove
nums.remove(99)              # by VALUE
nums.pop()                   # last → .removeLast()
nums.pop(0)                  # first → .removeFirst()
del nums[2]                  # by index
nums.clear()                 # all → .removeAll()

# Access
nums[0]     nums[-1]         # first / LAST
nums[1:4]                    # slice

# Search & Sort
3 in nums                    # .contains(3)
nums.index(3)                # .firstIndex(of:)
sorted(nums)                 # NEW sorted → .sorted()
nums.sort(reverse=True)      # in-place desc

# Aggregate
len(nums)  min(nums)  max(nums)  sum(nums)

List Comprehensions ⭐ PYTHON'S SUPERPOWER

# Map:        nums.map { $0 * 2 }
doubled = [x * 2 for x in nums]

# Filter:     nums.filter { $0 % 2 == 0 }
evens = [x for x in nums if x % 2 == 0]

# Map+Filter combined
result = [x * 2 for x in nums if x % 2 == 0]

# CompactMap: items.compactMap { $0 }
cleaned = [x for x in items if x is not None]

# FlatMap:    [[1,2],[3,4]].flatMap { $0 }
flat = [x for sub in nested for x in sub]

# Dict comprehension
squares = {x: x**2 for x in range(6)}

Dictionaries

user = {"name": "Ali", "age": 25}

user["name"]                   # "Ali" (KeyError if missing!)
user.get("phone", "N/A")      # safe — like dict["k", default:]
user["email"] = "a@b.c"       # add/update
user.update({"age": 26})       # merge
merged = {**d1, **d2}           # spread merge
del user["age"]                # remove
user.pop("age", None)         # safe remove

for k, v in user.items():     # iterate pairs
"name" in user                 # key exists?

Tuples & Sets

# Tuples — immutable
point = (10, 20)
x, y = point              # destructure

# Named tuples
from collections import namedtuple
Point = namedtuple("Point", ["x", "y"])
p = Point(10, 20); p.x  # 10

# Sets
colors = {"red", "blue"}
colors.add("green")
colors.discard("red")     # safe remove
a & b  # intersection   a | b  # union
a - b  # difference     a ^ b  # symmetric diff

collections Module — Power Tools BONUS

from collections import Counter, defaultdict, deque

Counter("banana")          # {'a':3, 'n':2, 'b':1}
Counter("banana").most_common(2)

dd = defaultdict(list)
dd["fruits"].append("apple") # no KeyError!

q = deque([1,2,3])
q.appendleft(0)             # O(1) vs list's O(n)

06 Control Flow

🍎 Swift
if score > 90 {
    print("A")
} else if score > 80 {
    print("B")
} else {
    print("C")
}
for i in 0..5 { }
for (i,v) in arr.enumerated() { }
🐍 Python
if score > 90:
    print("A")
elif score > 80:
    print("B")
else:
    print("C")

for i in range(5):
for i, v in enumerate(arr):

range() Complete

range(5)            # 0,1,2,3,4
range(2, 8)         # 2,3,4,5,6,7
range(0, 10, 2)     # 0,2,4,6,8
range(10, 0, -1)   # 10,9,...,1

Looping Patterns

# Enumerate with start
for i, item in enumerate(fruits, start=1):
    print(f"{i}. {item}")

# Zip — pair two lists
for name, age in zip(names, ages):
    print(f"{name} is {age}")

# Reversed
for item in reversed(nums): ...

# for/else — unique to Python!
for item in items:
    if item == target: break
else:
    print("Not found!")  # runs if NO break

Operators & Ternary

# Logical: and, or, not (not &&, ||, !)
# Chained comparison — Python exclusive!
if 0 < x < 100:           # clean!
if 1 <= age <= 120:

# Ternary (reversed from Swift!)
r = "yes" if x > 0 else "no"

# Identity
x is None      x is not None

match/case PYTHON 3.10+

match command:
    case "quit":              exit()
    case "hello" | "hi":     print("Hi!")
    case [x, y]:              print(f"pair: {x},{y}")
    case {"name": name}:      print(name)
    case _:                   print("default")

07 Functions — Complete Guide

🍎 Swift
func greet(name: String,
           loud: Bool = false
) -> String {
    return "Hi \(name)"
}
greet(name: "Ali")
🐍 Python
def greet(name: str,
          loud: bool = False
) -> str:
    return f"Hi {name}"

greet("Ali")

*args and **kwargs ⭐ NO SWIFT EQUIVALENT

def log(*args):                # variadic positional
    for a in args: print(a)

def config(**kwargs):           # variadic keyword
    for k, v in kwargs.items():
        print(f"{k} = {v}")

log(1, 2, 3)
config(theme="dark", lang="en")

Multiple Returns & Docstrings

def get_user():
    return "Ali", 25, "KL"     # returns tuple

name, age, city = get_user()
name, *rest = get_user()       # rest = [25, "KL"]
_, age, _ = get_user()         # ignore with _

def calc_bmi(weight: float, height: float) -> float:
    """Calculate Body Mass Index.

    Args:
        weight: Weight in kg
        height: Height in meters
    Returns:
        BMI as float
    """
    return weight / height ** 2

08 Classes & OOP

🍎 Swift
class Dog {
    var name: String
    init(name: String) {
        self.name = name
    }
    func bark() -> String {
        return "\(name) barks!"
    }
}
🐍 Python
class Dog:
    def __init__(self, name: str):
        self.name = name

    def bark(self) -> str:
        return f"{self.name} barks!"

⚡ Key Differences 1. Every method needs explicit self · 2. Constructor is __init__ · 3. No new keyword · 4. Properties created inside __init__ · 5. No access modifiers — use _ convention

Inheritance & @property

class Puppy(Dog):                    # class Puppy: Dog
    def __init__(self, name, toy):
        super().__init__(name)        # super.init(name:)
        self.toy = toy
    def bark(self):                  # override (no keyword!)
        return f"{self.name} yips!"

# Computed property
class Circle:
    def __init__(self, r): self._r = r

    @property
    def area(self):                # var area: Double { }
        return 3.14159 * self._r ** 2

    @property
    def radius(self): return self._r
    @radius.setter
    def radius(self, val):
        if val < 0: raise ValueError
        self._r = val

Dunder Methods ⭐ IMPORTANT

class Money:
    def __init__(self, amt): self.amt = amt
    def __repr__(self):      return f"Money({self.amt})"   # debugDescription
    def __str__(self):       return f"${self.amt:.2f}"    # description
    def __eq__(self, o):     return self.amt == o.amt     # Equatable
    def __lt__(self, o):     return self.amt < o.amt      # Comparable
    def __add__(self, o):    return Money(self.amt+o.amt) # + operator
    def __len__(self):      return abs(int(self.amt))    # len()
    def __getitem__(self,k): ...                            # subscript

@dataclass — Like Swift Structs ⭐ USE THIS

from dataclasses import dataclass, field

@dataclass
class User:
    name: str
    age: int
    email: str = ""
    tags: list = field(default_factory=list)

# Auto: __init__, __repr__, __eq__  (like struct + Equatable!)
u1 = User("Ali", 25)
u2 = User("Ali", 25)
u1 == u2   # True!

@dataclass(frozen=True)       # immutable!
class Point:
    x: float; y: float

@classmethod & @staticmethod

class User:
    _count = 0
    def __init__(self, name):
        self.name = name; User._count += 1

    @classmethod                      # convenience init
    def from_json(cls, data):
        return cls(data["name"])

    @staticmethod                     # static func
    def validate(name): return len(name) > 0

09 Protocols → Abstract Base Classes NEW

🍎 Swift
protocol Drawable {
    func draw()
    var color: String { get }
}
class Circle: Drawable {
    var color = "red"
    func draw() { }
}
🐍 Python
from abc import ABC, abstractmethod

class Drawable(ABC):
    @abstractmethod
    def draw(self): ...
    @property
    @abstractmethod
    def color(self): ...

class Circle(Drawable):
    color = "red"
    def draw(self): ...
💡 Duck Typing Python mostly uses "duck typing" — if it has the method, it works. You often don't need formal ABCs. Just call the method.

10 Optionals → None Handling

🍎 Swift
var name: String? = nil
if let n = name { print(n) }
let r = name ?? "Unknown"
guard let n = name else { return }
name?.uppercased()
🐍 Python
name = None
if name is not None: print(name)
r = name or "Unknown"
if name is None: return
name.upper() if name else None
🚨 Falsy Trap name or "default" also treats "", 0, [], False as falsy. For exact nil-coalescing:
name if name is not None else "default"

Safe Navigation Patterns

# Swift: user?.address?.city

# Pattern 1 — try/except (most Pythonic)
try:
    city = user.address.city
except AttributeError:
    city = None

# Pattern 2 — for dicts
city = data.get("user", {}).get("address", {}).get("city")

11 Closures → Lambdas

🍎 Swift
let double = { (x:Int) -> Int in
    return x * 2
}
nums.sorted { $0 > $1 }
nums.map { $0 * 2 }
nums.filter { $0 > 3 }
nums.reduce(0, +)
🐍 Python
double = lambda x: x * 2

sorted(nums, reverse=True)
[x * 2 for x in nums]       # prefer!
[x for x in nums if x>3]  # prefer!
sum(nums)
✅ Comprehensions Beat map/filter [x * 2 for x in nums] is faster and more readable than list(map(lambda x: x*2, nums))

Sorting with Key Functions

users = [{"name": "Bo", "age": 30}, {"name": "Ali", "age": 25}]
sorted(users, key=lambda u: u["age"])   # sort by age
sorted(words, key=len)                  # sort by length
sorted(words, key=str.lower)             # case-insensitive

12 Error Handling

🍎 Swift
do {
    let data = try loadFile()
} catch AppError.notFound {
    ...
} catch {
    print(error)
}
🐍 Python
try:
    data = load_file()
except FileNotFoundError:
    ...
except Exception as e:
    print(e)
finally:
    print("cleanup")  # defer{}

Custom Errors & Common Exceptions

class AppError(Exception): pass
class NotFound(AppError): pass
raise NotFound("User missing")
ExceptionWhen
ValueErrorWrong value
TypeErrorWrong type
KeyErrorDict key missing
IndexErrorList out of range
AttributeErrorNo such property/method
FileNotFoundErrorFile doesn't exist
ZeroDivisionError÷ by zero
💡 EAFP vs LBYL Swift: "Look Before You Leap" (if let, guard). Python: "Easier to Ask Forgiveness" — just try it and catch errors. try/except is normal flow control in Python.

13 Modules, Packages & Imports

Import Styles

import os                       # whole module
from os import path             # specific item
from os import path as p       # alias
import json as j               # module alias

Essential Standard Library

ModulePurposeSwift
os / pathlibFile systemFileManager
jsonJSON encode/decodeCodable
datetimeDates & timesFoundation.Date
reRegular expressionsNSRegularExpression
math / randomMath & randomFoundation
collectionsCounter, deque
itertoolsIterator toolsSequence ext
functoolsreduce, cache
dataclassesAuto classesstruct
unittest/pytestTestingXCTest
loggingLoggingos.log
sqlite3SQLite DBCore Data

pip & Virtual Environments

# Install
pip install requests flask numpy

# Virtual env (one per project!)
python3 -m venv .venv
source .venv/bin/activate     # macOS/Linux
pip install -r requirements.txt
pip freeze > requirements.txt
deactivate

14 File I/O & JSON

Reading & Writing

# Write
with open("out.txt", "w") as f:
    f.write("Hello\n")

# Read all
with open("out.txt") as f:
    content = f.read()

# Read line by line (memory efficient)
with open("big.txt") as f:
    for line in f:
        print(line.strip())

# Append
with open("log.txt", "a") as f: ...

# Binary (like Data in Swift)
with open("img.png", "rb") as f: data = f.read()
⚡ Always use with — it auto-closes the file like defer.

JSON — Way Easier Than Codable

import json

data = {"name": "Ali", "age": 25}
json_str = json.dumps(data, indent=2)    # → JSON string
obj = json.loads(json_str)               # → dict

# File I/O
with open("data.json") as f:     data = json.load(f)
with open("data.json","w") as f: json.dump(data, f, indent=2)

pathlib — Modern Paths ⭐ USE THIS

from pathlib import Path

p = Path("docs") / "report.txt"   # like URL!
p.exists()   p.is_file()   p.is_dir()
p.write_text("Hello")
content = p.read_text()
p.name  p.stem  p.suffix  p.parent

for f in Path(".").glob("*.py"): print(f)
Path("output").mkdir(exist_ok=True)

15 Async / Await FAMILIAR!

🍎 Swift
func fetch() async throws -> User {
    let (data,_) = try await
        URLSession.shared.data(from:url)
    return try JSONDecoder()
        .decode(User.self, from:data)
}
Task { try await fetch() }
🐍 Python
import asyncio, aiohttp

async def fetch() -> dict:
    async with aiohttp.ClientSession() as s:
        async with s.get(url) as r:
            return await r.json()


asyncio.run(fetch())

Concurrent Tasks

async def main():
    # Run 3 tasks at once (like async let / TaskGroup)
    results = await asyncio.gather(
        fetch(1), fetch(2), fetch(3)
    )

    # With timeout
    try:
        r = await asyncio.wait_for(fetch(1), timeout=5)
    except asyncio.TimeoutError: ...
💡 Python async is single-threaded (event loop, like JS). For CPU-heavy work use multiprocessing. Async is best for I/O.

16 Generators & Iterators PYTHON EXCLUSIVE

yield — Lazy Sequences

def countdown(n):
    while n > 0:
        yield n       # pauses, returns n
        n -= 1

for x in countdown(5): print(x)  # 5,4,3,2,1

# Generator expression — lazy list comprehension
squares = (x**2 for x in range(1_000_000))
# Uses almost NO memory!
next(squares)  # 0
next(squares)  # 1

# Practical — read huge files
def read_big(path):
    with open(path) as f:
        for line in f: yield line.strip()
💡 Like AsyncSequence but synchronous. range(), enumerate(), zip(), map() all return generator-like objects!

17 Decorators — Like Property Wrappers

How They Work

import time

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        print(f"{func.__name__} took {time.time()-start:.2f}s")
        return result
    return wrapper

@timer
def slow(): time.sleep(1)

slow()  # "slow took 1.00s"

Built-in Decorators You'll Use

@property         # computed property
@staticmethod     # static func
@classmethod      # factory/convenience init
@dataclass        # auto init/repr/eq
@abstractmethod   # protocol requirement

from functools import cache
@cache            # memoization — caches results
def fib(n):
    if n < 2: return n
    return fib(n-1) + fib(n-2)

fib(100)  # instant! (without @cache = impossibly slow)

18 HTTP & API Calls YOUR URLSession

requests Library

# pip install requests
import requests

# GET
r = requests.get("https://api.example.com/users")
r.status_code    # 200
data = r.json()  # auto-decode → dict

# GET with params
r = requests.get(url, params={"q": "python", "page": 1})

# POST with JSON
r = requests.post(url,
    json={"name": "Ali"},
    headers={"Authorization": "Bearer TOKEN"}
)

r.raise_for_status()  # raises on 4xx/5xx
✅ Comparison Swift: URLSession + JSONDecoder = ~10 lines. Python: requests.get(url).json() = 1 line.

19 Testing — Your XCTest NEW

pytest

# pip install pytest
# test_math.py

def test_add():
    assert add(2, 3) == 5

def test_error():
    with pytest.raises(ValueError):
        create_user("")

# Parametrize (like @Test(arguments:))
@pytest.mark.parametrize("a,b,expected", [
    (1, 2, 3), (0, 0, 0), (-1, 1, 0),
])
def test_add_many(a, b, expected):
    assert add(a, b) == expected

# Fixtures (like setUp)
@pytest.fixture
def user(): return User("Ali", 25)

def test_greet(user):
    assert "Ali" in user.greet()

# Run: pytest -v

20 Pythonic Tips ⭐ MUST READ

1. Truthiness

# ❌ if len(lst) > 0:  /  if name != "":
# ✅ if lst:  /  if name:  /  if x is not None:

2. Unpacking

first, *rest = [1,2,3,4]  # first=1, rest=[2,3,4]
a, b = b, a              # swap
func(*args, **kwargs)    # spread into call

3. Walrus Operator :=

if (n := len(data)) > 10:
    print(f"Too long: {n}")

while (line := f.readline()) != "":
    process(line)

4. One-Liners

any(x > 0 for x in nums)       # any match?
all(x > 0 for x in nums)       # all match?
min(users, key=lambda u: u.age)  # min by key
if 18 <= age <= 65:              # chained comparison
{**d1, **d2}                     # merge dicts
"hello"[::-1]                    # reverse string
[x for sub in nested for x in sub]  # flatten
list(dict.fromkeys(items))       # unique, keep order

5. Debug Print (3.8+)

x = 42
print(f"{x=}")                # "x=42" self-documenting!
print(f"{x=}, {type(x)=}")  # "x=42, type(x)=<class 'int'>"
breakpoint()               # drops into debugger (pdb)

6. Pattern Translation Table

SwiftPython
guard let x = y else { return }if y is None: return; x = y
.compactMap { $0 }[x for x in arr if x is not None]
.first(where: { $0 > 5 })next((x for x in arr if x > 5), None)
.contains(where: { $0 > 5 })any(x > 5 for x in arr)
.allSatisfy { $0 > 0 }all(x > 0 for x in arr)
defer { }try/finally or with
extensionJust add methods (monkey-patch)
enum + associated valuesdataclass subclasses or match/case

21 Complete Quick Reference

PythonSwiftWhat
deffuncDefine function
selfselfInstance ref (explicit!)
__init__initConstructor
NonenilNull
True / Falsetrue / falseBooleans (CAPITAL!)
and / or / not&& / || / !Logic
elifelse ifElse-if
len(x)x.countLength
range(n)0..<nRange
enumerate().enumerated()Index+value
zip(a,b)zip(a,b)Pair sequences
isinstance()is / as?Type check
raisethrowThrow error
exceptcatchCatch error
finallydeferAlways runs
passEmpty block
print()print()Same! 🎉
importimportImport
pipSPM/PodsPackage mgr
@propertyvar { get }Computed prop
@staticmethodstatic funcStatic method
@classmethodconvenience initFactory
@dataclassstructData container
lambda{ closure }Anonymous func
f"...{x}""\(x)"Interpolation
with open()Auto-close context
x if c else yc ? x : yTernary
**pow()Power
//Int(a/b)Floor division
yieldGenerator
async defasync funcAsync function
awaitawaitAwait result
assertXCTAssertTest assertion
breakpoint()lldbDebugger
[x for x in].map { }Comprehension
is / is not=== / !==Identity
in.contains()Membership
snake_casecamelCaseNaming
You're ready to Python 🐍
Made for Swift devs who want to learn Python fast ⚡