Skip to content

Latest commit

 

History

History
416 lines (308 loc) · 11.2 KB

File metadata and controls

416 lines (308 loc) · 11.2 KB

Python for JS Developers — DSA Interview Notes

Goal: get you writing Python fluently for DSA (Google/Meta/Airbnb/Atlassian-style interviews). Each section = concept → JS vs Python → example → Task (do it before moving on).


1. Variables & Basic Types

No let/const. No semicolons. Indentation = blocks (4 spaces, always).

x = 10          # like let x = 10
name = "Akshay" # str
is_ok = True    # capital T/F (not true/false)
nothing = None  # like null/undefined

Task: Declare an int, a string, a bool, and None. Print all four with print().


2. print & f-strings (your console.log + template literals)

age = 6
print(f"Akshay has {age} years exp")   # f-string == `${}` template literal
print("a", "b", sep="-")               # a-b

Task: Print "2 + 2 = 4" using an f-string that actually computes 2+2 inside {}.


3. Indentation = Braces

There is no {}. The colon : starts a block, indentation defines scope.

if age > 5:
    print("senior")
else:
    print("junior")

Task: Rewrite this JS as Python:

if (n % 2 === 0) { console.log("even") } else { console.log("odd") }

4. Operators — the gotchas

  • == in Python already does value comparison (no === needed; Python has no type coercion like JS).
  • and, or, not — not &&, ||, !.
  • // is integer (floor) division. / always gives float.
  • ** is power (not ^, that's XOR in Python).
  • % works like JS but careful with negatives: -7 % 3 == 2 in Python (JS gives -1).
print(7 // 2)   # 3
print(7 / 2)    # 3.5
print(2 ** 10)  # 1024
print(-7 % 3)   # 2  <-- classic interview trap

Task: Predict then verify: print(-7 // 2) and print(-7 % 2).


5. Lists (your Array)

Mutable, ordered, like JS arrays but with more built-in slicing power.

arr = [1, 2, 3]
arr.append(4)          # push
arr.pop()               # pop last
arr.pop(0)              # remove index 0 (shift)
arr.insert(0, 99)       # unshift-like
len(arr)                # arr.length
arr[-1]                 # last element (no arr[arr.length-1]!)

Slicing arr[start:stop:step] — huge for DSA, no JS equivalent this clean:

arr = [0,1,2,3,4,5]
arr[1:4]     # [1,2,3]
arr[:3]      # [0,1,2]
arr[::-1]    # reversed list! [5,4,3,2,1,0]
arr[::2]     # every 2nd element

Task: Given arr = [10,20,30,40,50], using slicing only: get the last 3 elements, and get the reversed array.


6. Tuples — immutable lists

Used for fixed pairs (like coordinates), and as dict keys (lists can't be dict keys, tuples can).

point = (3, 4)
x, y = point   # destructuring, same as JS const [x,y] = point

Task: Create a tuple (row, col) and unpack it into two variables in one line.


7. Dictionaries (your Object / Map)

Closer to JS Map than Object — any hashable type as key, ordered (insertion order, Python 3.7+).

d = {"a": 1, "b": 2}
d["c"] = 3                 # add
d.get("z", 0)               # like d["z"] ?? 0, safe default
"a" in d                    # key existence check (like 'a' in obj)
del d["a"]                  # delete key
for k, v in d.items():      # iterate entries
    print(k, v)

Task: Count characters in "banana" into a dict {char: count} using d.get(c, 0) + 1.


8. Sets (your Set)

Same idea as JS Set — unique, unordered, O(1) lookup.

s = {1, 2, 3}
s.add(4)
s.remove(2)
2 in s          # membership check
s1 & s2         # intersection
s1 | s2         # union
s1 - s2         # difference

Task: Given two lists, find common elements using set intersection in one line.


9. Strings — immutable, but very rich API

s = "Hello World"
s.lower(), s.upper()
s.split(" ")          # ["Hello", "World"]
"-".join(["a","b"])   # "a-b"
s[::-1]               # reverse a string (no reverse() method!)
s.strip()             # trim
ord('a'), chr(97)     # char <-> ascii code (used A LOT in DSA)

Task: Check if a string is a palindrome using slicing (s == s[::-1]).


10. Loops — for is different (no classic C-style for)

for i in range(5):        # 0,1,2,3,4  (like for(let i=0;i<5;i++))
    print(i)

for i in range(2, 10, 2):  # start, stop, step
    print(i)

for i, val in enumerate(arr):   # index + value together
    print(i, val)

for a, b in zip(list1, list2):  # iterate two lists in parallel
    print(a, b)

Task: Print index and value for ["x","y","z"] using enumerate.


11. List Comprehensions — Python's superpower (replaces .map/.filter)

squares = [x*x for x in range(10)]              # like arr.map(x => x*x)
evens = [x for x in range(20) if x % 2 == 0]    # like arr.filter(...)
pairs = [(i,j) for i in range(3) for j in range(3)]  # nested loops in one line

Task: Using one comprehension, build a list of squares of only the even numbers from 0–20.


12. Functions & Default Args

def add(a, b=0):        # default param, same idea as JS
    return a + b

add(a=5, b=3)            # named args (great for readability)

square = lambda x: x*x   # arrow function equivalent

Task: Write a function greet(name, greeting="Hello") returning an f-string, call it both with and without greeting.


13. *args and **kwargs (rest params / spread)

def total(*nums):          # like function total(...nums)
    return sum(nums)

def show(**info):          # like spreading an object's keys
    for k, v in info.items():
        print(k, v)

total(1,2,3)          # 6
show(name="A", age=6)

Task: Write a function that accepts any number of numbers and returns the max without using max().


14. Unpacking / Multiple Assignment

a, b = 1, 2
a, b = b, a              # swap! no temp variable needed
first, *rest = [1,2,3,4] # rest = [2,3,4], like JS const [first, ...rest]

Task: Swap two variables x, y = 5, 10 in one line, then print both.


15. collections.Counter — frequency map in one line

Replaces the manual "build a dict of counts" loop you'll write 100 times in DSA.

from collections import Counter
c = Counter("mississippi")
c.most_common(2)     # top 2 frequent chars: [('i',4), ('s',4)]

Task: Use Counter to check if two strings are anagrams (Counter(s1) == Counter(s2)).


16. collections.defaultdict — no more if key not in d

from collections import defaultdict
d = defaultdict(list)
d["a"].append(1)     # no KeyError even though "a" wasn't set before
d["a"].append(2)

Task: Group a list of words by their first letter using defaultdict(list).


17. collections.deque — O(1) from both ends (queues, BFS)

Python lists are O(n) for pop(0). Use deque for BFS/queue problems.

from collections import deque
q = deque([1,2,3])
q.append(4)        # push right
q.appendleft(0)     # push left
q.popleft()          # O(1) dequeue — this is why we use it for BFS

Task: Implement BFS traversal skeleton for a grid using deque (just the loop structure, no real grid needed).


18. heapq — Python's priority queue (min-heap only)

No built-in max-heap; negate values for max-heap behavior.

import heapq
h = []
heapq.heappush(h, 5)
heapq.heappush(h, 1)
heapq.heappush(h, 3)
heapq.heappop(h)     # 1 (smallest first)

# max-heap trick: push negative values
heapq.heappush(h, -5)

Task: Push [5,1,9,3] onto a heap and pop all elements — confirm they come out sorted ascending.


19. Sorting — sorted() and .sort() with key

arr.sort()                          # in-place, like arr.sort() in JS but numeric by default!
sorted(arr, reverse=True)            # new list, descending
arr.sort(key=lambda x: x[1])         # sort by 2nd element of tuples/pairs
sorted(words, key=len)               # sort strings by length

Task: Sort a list of tuples [(1,'b'), (2,'a')] by the second element alphabetically.


20. Recursion — same as JS, but know the default limit

Python's default recursion depth is ~1000 (can hit RecursionError on deep recursion — mention this in interviews if relevant).

def factorial(n):
    if n <= 1:
        return 1
    return n * factorial(n - 1)

Task: Write a recursive Fibonacci function, then add memoization using @lru_cache (see next section).


21. @lru_cache — memoization in one line (huge time-saver in interviews)

from functools import lru_cache

@lru_cache(maxsize=None)
def fib(n):
    if n <= 1:
        return n
    return fib(n-1) + fib(n-2)

Task: Time (mentally/logically) how fib(35) differs with vs without @lru_cache.


22. Classes — for linked lists / trees (very common in DSA)

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

node = ListNode(5)
print(node.val)

No this — use self, and it must be the first parameter of every method, explicitly.

Task: Define a TreeNode class with val, left, right (default None), then create one node.


23. Truthy/Falsy & None checks

Falsy: 0, 0.0, "", [], {}, set(), None, False.

if not arr:          # same as if (arr.length === 0) in JS
    print("empty")

if node is None:      # use `is None`, not `== None`
    ...

Task: Write a one-liner that returns "empty" if a list is empty, else "has items".


24. Common Pitfalls Coming From JS

JS habit Python fix
arr.length len(arr)
array.push() list.append()
array.includes(x) x in list
Object.keys(obj) dict.keys()
JSON.stringify str() / json.dumps()
=== just == (no coercion issue in Python)
null/undefined None only
// comment # comment
string concatenation with + on mixed types must str(x) first, no auto-coercion

Task: Fix this broken-from-habit code: print("Count: " + 5) — make it work in Python.


25. Two-Pointer / Sliding Window Building Blocks

Not a new syntax feature — just the pattern combining slicing + while:

left, right = 0, len(arr) - 1
while left < right:
    # do work
    left += 1
    right -= 1

Task: Using two pointers, check if a list is a palindrome (arr == arr[::-1] is the lazy way — now do it manually with while left < right).


Quick-Reference Cheat Sheet

len(x)              length
arr[-1]             last element
arr[::-1]           reverse
"".join(list)        list -> string
list(s)              string -> list of chars
sum(arr), max(arr), min(arr)
sorted(arr, key=..., reverse=True)
ord(c), chr(n)        char <-> code
Counter(iterable)     frequency map
defaultdict(int/list) auto-default dict
deque()               O(1) queue both ends
heapq                 min-heap
@lru_cache            memoization

Suggested order to work through this

Days 1–2: sections 1–11 (syntax + core data structures) Day 3: sections 12–14 (functions/unpacking) Day 4: sections 15–18 (collections/heapq — this is what makes Python fast for DSA) Day 5: sections 19–25 (sorting, recursion, classes, patterns)

Once comfortable, jump straight into solving array/string/hashmap LeetCode problems in Python — you'll pick up the rest by doing.