Syntax Comparison: Swift vs Python

Kiran Sarella
11 min readApr 10, 2020

Sharing my notes that I prepared to remember the python syntax from already known language syntax. (Swift 4.2; Python 3.7)

“The Loci method is one of the most ancient memorization tools known, and is based on attaching individual items you need to remember, to individual points on a route you are familiar with, so you can easily recall the items as you “walk” that route in your mind.”

  • Basics
  • Collection Types
  • Class, Struct
  • Closures
  • Exception Handling
  • Unit Testing

Import Modules

Swift

import Foundation

typealias a module

typealias SMSomeStruct = SomeModule.SomeStruct

Import only parts from a module

import struct­ SomeModule.SomeStruct
import class­ SomeModule.SomeClass
import func SomeModule.someFunc

Python

import calculator

typealias a module

import calculator as calc

Import only parts from a module

from calculator import multiply# usage
result = multiply(2, 4)

Constants

Swift

let maximumHeight = 50

Python

Create constant.py file (global file)

PI = 3.14
GRAVITY = 9.8
MAXIMUM_HEIGHT = 50

Usage:

import constantconstant.MAXIMUM_HEIGHT

Variables

Swift

var userName = "Sit Bibendum"
userName = "Malesuada Mollis"

Python

userName = "Sit Bibendum"
userName = "Malesuada Mollis"
# Assigning multiple values to multiple variables
a, b, c = 5, 3.2, "Hello"
# to assign the same value to multiple variables at once
x = y = z = 1000

Comments

Swift

// single comment/* multi line comment */

Python

# python comment, no multiline comment

Print

Swift

let id = 525
let name = "Porta Tortor"
print(id, name) // 525 Porta Tortor
print(id, name, separator: ", ") // 525, Porta Tortor

Python

id = 525
name = "Porta Tortor"
print(id, name) # 525 Porta Tortor
print(id, name, sep=', ') # 525, Porta Tortor

Print Terminator Usage

Swift

for i in 1 ..< 10 {
print(i, terminator: " ")
if i % 3 == 0 {
print()
}
}
output: 1 2 3 4 5 6 7 8 9

Python

for i in range(1, 10):
print(i, end=' ')
if i % 3 == 0:
print()
output: 1 2 3 4 5 6 7 8 9

Multiline Strings

Swift

let html =
"""
<html>
<body> </body>
</html>
"""

Python

html = """
<html>
<body> </body>
</html>
"""

(or) using single quotes

html2 = '''
<html>
<body> </body>
</html>
'''

String Interpolation

Swift

let id = 525
let name = "Porta Tortor"
let msg = "\(id): \(name)" // 525: Porta Tortor

Python

id = 525
name = "Porta Tortor"
msg = "%d: %s" % (id, name) # 525: Porta Tortormsg = "{}: {}".format(id, name) # 525: Porta Tortormsg = "{0}: {1}".format(id, name) # 525: Porta Tortor

String Concatenation

Swift

let userID = 525
let firstName = "Cursus"
let lastName = "Dolor"
let text = firstName + " " + lastName + " (" + String(userID) + ")."output: Cursus Dolor (525).

Python

userID = 525
firstName = "Cursus"
lastName = "Dolor"
text = firstName + " " + lastName + " (" + str(userID) + ")."output: Cursus Dolor (525).

How to get object type ?

Swift

let height = 5.7
type(of: height) // Double.Type
if height is Int {
// ..
}

Python

height = 5.7
type(height) # <type 'float'>
if (type(height) is float):
# ..

String to Int

Swift

let userIDString = "525"
let userID = Int(userIDString)

Python

user_id_string = "525"
user_id = int(user_id_string)

Binary to Number

Swift

let binary = "11001"
let number = Int(binary, radix: 2) // 25

Python

binary = "11001"
number = int(binary,2) // 25

Boolean

Swift

var isEnabled = true           // false

Python

isEnabled = True   		# False

Tuples

Swift

let http404Error = (404, "Not Found")let code = http404Error.0
let message = http404Error.1
// or
let (statusCode, statusMessage) = http404Error

Python

http404Error = (404, "Not Found")code = http404Error[0]
message = http404Error[1]

Nil, None

Swift

var email: String? = nil

Python

email = None

del Statement

Swift

// ??

Python

name = Mattis Ridiculus
del name # object will be deleted completly
print(name) # NameError: "name 'name' is not defined"

If Statement

Swift

var email: String? = nil// Optional wrap
if let email = email {
print(email)
} else {
print("n/a")
}
// Force unwrap
if email != nil {
print(email!)
} else {
print("n/a")
}
Output: n/a

Python

email = Noneif email is not None:
print(email)
else:
print("n/a")

or

if email != None:
print(email)
else:
print("n/a")

Output: n/a

If with Multiple Conditions

Swift

if self.x == other.x && self.y == other.y {
return true
} else {
return false
}

Python

if (self.x == other.x and self.y == other.y):
return True
else:
return False

Escape characters

Swift

let text = "one\ntwo\nthree"let regExp = "Language: \"Swift\", version: \"4.2\""

Python

text = "one\ntwo\nthree"regExp = "Language: \"Python\", version: \"3.7\""# one two three
# Language: "Python", version: "3.7"

Counting Characters

Swift

let text = "abc 123"
text.count // 7

Python

text = "abc 123"
len(text) # 7

Enum

Swift

enum Color: Int {
case red = 1
case green
case blue

var name: String {
switch self {
case .red:
return "red"
case .green:
return "green"
case .blue:
return "blue"
}
}
}
// Usage:
Color.green
Color.green.name
Color.green.rawValue
let selectedColor = Color.greenif case Color.green = selectedColor {
print("Selected right color")
} else {
print("Wrong color selected \(selectedColor.name)")
}

Python

from enum import Enumclass Color(Enum):
red = 1
green = 2
blue = 3

Color.green # Color.green
Color.green.name # green
Color.green.value # 2
# Usage:
selectedColor = Color.green
if selectedColor is Color.green:
print("Selected Right color")
else:
print("Wrong color selected: {}".format(selectedColor.name))

Switch

Swift

switch input {
case 0:
//..
case 1:
break
case 2:
//..
}

Python

python does not have any switch case statement. 
Alternatively we use dictionary mapping.

Pass by reference

Swift

func swapInts(a: inout Int, b: inout Int) {
let temp = a
a = b
b = temp
}
var a = 50
var b = 100
swapInts(a: &a, b: &b)
print(a, b)

Python

There are no variables in Python. There are names and objects in - Python and together they appear like variables

Decorators

Swift

// TODO: ??

Python

def validateInputs(input_function):
def validation(a, b):
if b == 0:
print("Can't divide by 0")
return
return input_function(a, b) # call input function
return validation
@validateInputs
def div(a, b):
return a / b
div(10,0)# need to check how to achieve Decorator Pattern using python decorators. (ie.. without modifying the source code file)

Yield (instead of return), Next

Swift

// achieve using closures
func makeIncrementer(_ amount: Int) -> () -> Int {
var runningTotal = 0
func incrementer() -> Int {
runningTotal += amount
return runningTotal
}
return incrementer
}
let incrementByTen = makeIncrementer(10)
incrementByTen()
incrementByTen()
for _ in 0..<10 {
print(incrementByTen())
}

Python

def makeIncrementer(amount):
runningTotal = 0
while True:
runningTotal += amount
yield runningTotal

incrementerByTen = makeIncrementer(10)
next(incrementerByTen) # 10
next(incrementerByTen) # 20
for i in range(10):
print(next(incrementerByTen)) # 30 40 ... 120

Collection Types

Array

Array Operations

Swift

var hetro: [Any] = ["one", 10, 2.5]hetro[0]
// Negative Indexing not allowed
hetro[1] = "100"hetro.remove(at: 0)hetro.append("five")
hetro.append(4.9)
hetro.append("five")
// No inbuilt method to remove an element directlyhetro.insert(10000, at: 1)

Python

hetro = ["one", 10, 2.5]hetro[0]     # one
# reverse index
hetro[-1] # 2.5
hetro[-2] # 10
hetro[1] = "100"# pop at index
hetro.pop(0)
# append
hetro.append("five")
hetro.append(4.9)
hetro.append("five")
# remove first occurances
hetro.remove("five")
# insert at index
hetro.insert(1, "100000")

Empty array

Swift

var list = [Any]()

Python

list = []

Multidimensional arrays

Swift

let matrix = [[1,2,3], [4,5,6], [7,8,9]]
matrix[0][0]
matrix[2][2]

Python

matrix = [[1,2,3], [4,5,6], [7,8,9]]
matrix[0][0]
matrix[2][2]

Array Length

Swift

let list = ["zero", "one", "two", "three", "four"]
list.count

Python

list = ["zero", "one", "two", "three", "four"]
len(list)

Array Slicing

Swift

let list = ["zero", "one", "two", "three", "four"]list[1...4]
list[..<2]
list[2...]

Python

list = ["zero", "one", "two", "three", "four"]list[1:4]    # ['one', 'two', 'three']
list[ :2] # ['zero', 'one']
list[2: ] # ['two', 'three', 'four']

list[start: end-1] understanding-pythons-slice-notation

Array with a Default Value

Swift

var countArray = Array(repeating: 0, count: 10)		
// [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Python

countArray = [0] * 10
# or
countArray = [0 for i in range(10)] # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

Set

Swift

var basket: Set = ["one", "two", "three"]let isExists = basket.contains("one")basket.insert("four")basket.update(with: "four") // if aleady contains will return `input`; else returns nil;// there is no inbuild method for appending listbasket.remove("four")basket.popFirst()basket.removeAll()

Python

basket = { "one", "two", "three"}
# or
basket = set({ "one", "two", "three"})
isExists = "one" in basketbasket.add("four")basket.update(["five", "six"])basket.remove("six")basket.discard("six") # If the item to remove does not exist, discard() will NOT raise an error.# take random element
random = basket.pop() # three
basket.clear() # set([])

Empty Set

Swift

var basket = Set<AnyHashable>()		// Set([])

Python

basket = set()						# set([])

Dictionaries

Swift

var info:[String: Any] = [
"name": "Elit Vestibulum",
"age": 43
]
let name = info["name"]info["age"] = 54info["country"] = "Cursus Elit"
info.updateValue("Nibh Dapibus", forKey: "city")
info.valuesinfo.keysinfo.removeValue(forKey: "age")info.removeAll()

Python

info = {
"name" : "Elit Vestibulum",
"age": 43
}
# get
name = info["name"]
name = info.get("name")
# update
info["age"] = 54
# add new pairs
info["country"] = "Cursus Elit"
info.update({"city": "Nibh Dapibus"})
# get all values
values = info.values()
# get all keys
keys = info.keys()
# remove pair
info.pop("age")
info.clear() # {}

Empty Dictionary

Swift

var info = [String: Any]()      // [:]

Python

info = dict()                  # {}

Class

Hello World

Swift

class MyClass {
init() {
print("Hello World")
}
}
let myObject = MyClass()

Python

class MyClass:
def __init__(self):
print("Hello World")

myObject = MyClass()

Basic Math Class Example

Swift

class Math {

let pi = 3.14

func areaOfCircle(radius r: Double) -> Double {
return pi * (r * r)
}

func sum(a: Int, b: Int) -> Int {
return a + b
}

}
let math = Math()
let area = math.areaOfCircle(radius: 10)
let sum = math.sum(a: 5, b: 2)

Python

class Math:
pi = 3.14 # default initializer; to access `self` is required (ie. self.pi)

def areaOfCircle(self, radius: float) -> float:
return self.pi * (radius * radius)

def sum(self, a, b):
return a + b

# Function annotations are completely optional metadata information about the types used by user-defined functions
def substract(self, a: int, b: int) -> int:
return a - b

math = Math()
area = math.areaOfCircle(10) # 314.0
sum = math.sum(2, 5) # 7
result = math.substract(2, 5) # -3

Init Params

Swift

class Table {

let multipler: Int

init(input: Int) {
self.multipler = input
}

func printTable(limit: Int = 10) {
for i in 1 ... limit {
print("\(multipler) * \(i) = \(i * multipler)")
}
print()
}
}
let table2 = Table(input: 2)
table2.printTable()
table2.printTable(limit: 5)

Python

class Table:
def __init__(self, input):
self.multipler = input

def printTable(self, limit = 10):
for i in range(1, limit):
print("%d * %d = %d" % (self.multipler, i,
self.multipler * i))
print()


table_2 = Table(2)
table_2.printTable()
table_2.printTable(5)
output:
2 * 1 = 2 ..... 2 * 9 = 18
2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 2 * 4 = 8

Class Inheritance, Overriding Methods

Swift

class Employee {
let id: Int
let name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
func printDetails() {
print("id: \(id)")
print("name: \(name)")
}
}
class Technician: Employee {
let labId: String
init(id: Int, name: String, labId: String) {
self.labId = labId
super.init(id: id, name: name)
}
override func printDetails() {
super.printDetails()
print("labId: \(labId)")
}
}
let technician = Technician(id: 2693, name: "Nibh Fringilla", labId: "LAB001")

Python

class Employee:
def __init__(self, id, name):
self.id = id
self.name = name

def printDetails(self):
print("id: %s" % (self.id))
print("name: %s" % (self.name))
class Technician(Employee):
def __init__(self, id, name, labID):
self.labID = labID
super().__init__(id, name)
# Override method
def printDetails(self):
super().printDetails()
print("labID: %s" % (self.labID))
technician = Technician(2693, "Nibh Fringilla", "LAB001")
professor.printDetails()
output:
id: 2693 name: Nibh Fringilla labID: LAB001

Private

Swift

class Hacker {

private var name = "Amet Lorem"

private func details() {
print(name)
}

func publicDetails() {
print("random name")
}
}
let hacker = Hacker()
hacker.publicDetails() // random name

Python

class Hacker:
__name = "Amet Lorem"
def __details(self):
print(self.__name)

def publicDetails(self):
print("random name")


hacker = Hacker()
hacker.publicDetails() # random name
# "'Hacker' object has no attribute '..'" -- error for below commands
hacker.name
hacker.__name
hacker.details()
hacker.__details()

Structs, Data Classes

Swift

struct Center {
let x: Float
let y: Float
}
// Equatable ~= __eq__
// Hashable ~= __hash__
// CustomStringConvertible ~= __repr__

Python

from dataclasses import dataclass@dataclass
class Center:
x: float
y: float

c1 = Center(4,5)
print(c1) # Center(x=4, y=5)

Adventage of Data Classses: Auto generated _init_, _repr_, _eq_, ..

ref: https://medium.com/mindorks/understanding-python-dataclasses-part-1-c3ccd4355c34

@dataclass(frozen = True)	# immutable# To control the auto generated methods
@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

same functionality using class:

class Center:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
if (self.x == other.x and self.y == other.y):
return True
else:
return False
def __repr__(self):
return 'Point(x=%s, y=%s)' % (self.x, self.y)
# .. have to implement all functions manually

Closures

Basic

Swift

var addTen = { $0 + 10 }
addTen(5) # 15

Python

lambda arguments: expression

Note: Only one expression (a + 10) is allowed with lambda functions.

addTen = lambda a: a + 10
addTen(5) # 15
# or use `def` if cannot achieve in single expressiondef addTen(a):
..
..
return a + 10

Multiple inputs

Swift

var product: ((Int, Int) -> (Int)) = { a, b in
return a * b
}
product(5, 10)

Python

product = lambda a, b: a * bproduct(5, 10)	# 50

Lambda function

Swift

func makeNTimes(_ n: Int) -> ((Int) -> Int) {
return { a in return a * n }
}
var doubler = makeNTimes(2)
doubler(10)
var tripler = makeNTimes(3)
tripler(10)

Python

def makeNTimes(n):
return lambda a: a * n

doubler = makeNTimes(2)
doubler(10) # 20
tripler = makeNTimes(3)
tripler(10) # 30

Map

Swift

let numbers = [1, 2, 3, 4, 5]let result = numbers.map { $0 * 2 }

Python

map(function, iterables)

numbers = [1, 2, 3, 4, 5]multiply2 = lambda x: x * 2result = list(map(multiply2, numbers))	# orresult = list(map(lambda x: x * 2, [1, 2, 3, 4, 5]))output:
[2, 4, 6, 8, 10]

Filter

Swift

let numbers = [1, 2, 3, 4, 5, 6]let result = numbers.filter { $0 % 2 == 0 }

Python

filter(function, iterable)

numbers = [1, 2, 3, 4, 5, 6]result = list(filter(lambda x : x % 2 == 0, numbers)) # [2, 4, 6]

Reduce

Swift

let numbers = [1, 2, 3, 4, 5, 6]let res = numbers.reduce(1) { (result, value) -> Int in
return result * value
}

Python

reduce(function, iterable)

from functools import reducenumbers = [1, 2, 3, 4, 5, 6]exp = lambda x: x * 2product = reduce(exp, numbers)  
# 720

Exception Handling

User-defined Exceptions

Swift

enum InputValidationError: Error {
case invalidInput(String)
}
func validateAge(_ age: Int) throws {
if age < 0 {
throw InputValidationError.invalidInput("Only positive integers are allowed")
}
}
do {
try validateAge(-2)
} catch InputValidationError.invalidInput(let message) {
print("Exception: ", message)
}

Python

class InputValidationError(Exception):
def __init__(self, message):
self.message = message
def validateAge(age):
if age < 0:
raise InputValidationError('Only positive integers are allowed')
try:
validateAge(-1)
except InputValidationError as error:
print("Exception: ", error.message)
except:
print("something is wrong")

Example

Swift

enum CommonError: Error {
case divisionByZero
}
func divide(_ a: Int, by b: Int) throws -> Int {
if b == 0 {
throw CommonError.divisionByZero
}
return a / b
}
var result: Int
do {
result = try divide(10, by: 0)
} catch CommonError.divisionByZero {
print("division by zero!")
} catch {
//
}
Note:
- In Swift there is no functionality to catch arbitrary runtime errors.
- no `
finally` in swift, so make use of `defer`

Python

def divide(x, y):
try:
result = x / y
except ZeroDivisionError:
print("division by zero!")
else:
print("result is ", result)
finally:
print(".. executing finally")

>> divide(2, 1)
output:
result is 2.0
.. executing finally
>> divide(2, 0)
division by zero!
.. executing finally

Unit Tests

Example

Swift

import XCTest
@testable import AppTarget
class AppHelperTests: XCTestCase {

let calculator = Calculator()

override func setUp() {
super.setUp()
// ..
}

override func tearDown() {
// ..
super.tearDown()
}

func testAdd() {
let result = calculator.add(2, 3)
XCTAssertEqual(result, 5)
}

func testMultiply() {
let result = calculator.multiply(2, 3)
XCTAssertEqual(result, 6)
}
}

Python

calculator.py

def add(a, b):
return a + b

def multiply(a, b):
return a * b
import unittest
import calculator
class TestCalculator(unittest.TestCase): def setUp(self):
pass

def tearDown(self):
pass

def test_add(self):
result = calculator.add(2, 3)
self.assertEqual(result, 5)

def test_multiply(self):
result = calculator.multiply(2, 3)
self.assertEqual(result, 6)

Running Tests

if __name__ == '__main__':
unittest.main()


# Console output:
..
--------------------------------------------------------------------
Ran 2 tests in 0.000s
OK

pass Statement:

used when a statement is required syntactically but you do not want any command or code to execute.

List of assets: ref: https://docs.python.org/2/library/unittest.html

Corrections are welcome :). Thank You.

--

--