Python Notebook

Embark on a journey through the Python programming language, exploring its fundamental concepts, advanced features, and practical applications. This comprehensive guide is designed for both beginners and experienced developers looking to deepen their understanding of Python and enhance their coding skills. Discover the versatility and power of one of the most popular programming languages in the world today.

·
...

Something i found interesting from learning Python

Mutable!

In Python, lists are mutable, and when you pass them as arguments, any change inside the function reflects outside.

Validation

1char.isdigit() # bool

set

1a = set([1, 2, 3])
2b = set([2, 3, 4])
3
4a - b     # ➜ {1}
5a | b     # ➜ {1, 2, 3, 4}
6a & b     # ➜ {2, 3}
7a ^ b     # ➜ {1, 4}

Set Operations

OperationMethod NameOperator
Differenceset1.difference(set2)set1 - set2
Unionset1.union(set2)set1 | set2
Intersectionset1.intersection(set2)set1 & set2
Symmetric Differenceset1.symmetric_difference(set2)set1 ^ set2
  • ✅ Cleaner
  • ✅ Faster to type
  • ✅ Interviewer-friendly (they love when you know this)

sorted() vs .sort() — Memory Tricks

Problem: Always forgetting which one returns a new list vs modifies in-place!

Solution 1: “ED = nEw Data” Mnemonic

1sorted(nums)    # sort-ED → has "ED" → returns nEw Data (new list)
2nums.sort()     # no "ED" → modifies in-place, returns None

Solution 2: Function vs Method Pattern

1sorted(x)  # Sounds like a FUNCTION → creates NEW thing (like print(), len())
2x.sort()   # Sounds like a METHOD → modifies EXISTING thing (like .append(), .pop())

When to use which:

  • Keep original? → Use sorted() to get a new sorted list
  • Save memory? → Use .sort() to sort in-place (no extra list created)
1# Example
2nums = [3, 1, 4, 1, 5]
3
4new_list = sorted(nums)    # nums unchanged, new_list = [1, 1, 3, 4, 5]
5nums.sort()                # nums is now [1, 1, 3, 4, 5], returns None
6
7# Common mistake:
8result = nums.sort()       # ❌ result is None, not the sorted list!

Quick test: Which one would you use to keep the original list unchanged? → sorted()

Tuple Unpacking with * — The “Explode” Operator

Concept: Think of * as “exploding” a tuple/list — it spreads elements out.

1# Without unpacking (nested)
2rank = 1
3country_data = ('CountryA', 2, 3, 4)
4output = (rank, country_data)
5print(output)  # (1, ('CountryA', 2, 3, 4)) ← nested!
6
7# With unpacking (flattened)
8output = (rank, *country_data)
9print(output)  # (1, 'CountryA', 2, 3, 4) ← flat! 💥

Use cases:

 1# 1. Flattening tuples
 2nums = (1, 2, 3)
 3result = (0, *nums)      # (0, 1, 2, 3)
 4
 5# 2. Combining lists
 6a = [1, 2]
 7b = [3, 4]
 8combined = [*a, *b]      # [1, 2, 3, 4]
 9
10# 3. Function arguments
11def my_func(a, b, c):
12    return a + b + c
13
14args = (1, 2, 3)
15my_func(*args)           # Same as my_func(1, 2, 3)

Memory trick: * = bomb emoji 💣 → explodes the container!

extended slicing

 1# extended slicing
 2# [start:stop:step]
 3# start: inclusive
 4# stop: exclusive
 5# step: optional
 6# default: start = 0, stop = len(list), step = 1
 7my_list = [10, 20, 30, 40, 50]
 8reversed_list = my_list[::-1]
 9print(reversed_list)
10
11my_string = "hello"
12reversed_string = my_string[::-1]
13print(reversed_string)
14
15# output
16# [50, 40, 30, 20, 10]
17# olleh

strip()

1text = "   example string with spaces   \n"
2trimmed_text = text.strip()
3print(f"Original: '{text}'")
4print(f"Trimmed:  '{trimmed_text}'")
5
6# Output:
7# Original: '   example string with spaces
8# '
9# Trimmed:  'example string with spaces'

🗺️ Roadmap Overview

This roadmap is structured to build my proficiency in Python and strengthen my understanding of fundamental data structures and algorithms. It is divided into several phases, each focusing on specific topics and associated problems.

Phase 1: Python Fundamentals

Before diving into problem-solving, ensure i’m comfortable with Python’s syntax and core concepts:

  • Data Types and Structures: Lists, Tuples, Dictionaries, Sets
  • Control Flow: Loops, Conditional Statements
  • Functions and Modules: Defining functions, Importing modules
  • List Comprehensions and Lambda Functions

Resources:

Phase 2: Arrays and Strings

These are foundational topics that frequently appear in interviews.

Phase 3: Two Pointers and Sliding Window

Techniques that optimize traversal of arrays and linked lists.

Phase 4: Hashing and Hash Maps

Efficient data retrieval and storage techniques.

Phase 5: Linked Lists

Understanding linked lists is crucial for many algorithmic problems.

Phase 6: Trees and Graphs

Explore hierarchical data structures and their traversal algorithms.

Phase 7: Dynamic Programming

Techniques for solving complex problems by breaking them down into simpler subproblems.

Phase 8: Advanced Topics

Delve into more complex data structures and algorithms.

Additional Resources

  • LeetCode 75 Study Plan: A curated list of 75 essential problems for interview preparation.
  • Top Interview 150 Study Plan: A comprehensive set of 150 classic interview questions.
  • NeetCode’s Blind 75: A popular list of algorithm practice problems with video explanations

🧩 LeetCode Practices

997. Find the Town Judge

Key Insight

Identify the town judge by tracking trust relationships: the judge is trusted by everyone else but trusts no one.

Python Implementation

 1class Solution(object):
 2    def findJudge(self, n, trust):
 3        """
 4        :type n: int
 5        :type trust: List[List[int]]
 6        :rtype: int
 7        """
 8
 9        # trust relationships are directed edges
10
11        # loop by n
12        # find from list
13        # if index is not found in list
14        # return index
15        # else return -1
16
17        nb_trusts = [0] * (n+1)
18        nb_trusted_by = [0] * (n+1)
19
20        for a, b in trust:
21            nb_trusts[a] += 1
22            nb_trusted_by[b] += 1
23
24        print("nb_trusts", nb_trusts)
25        print("nb_trusted_by", nb_trusted_by)
26
27
28        for i in range(1, n+1):
29            if nb_trusts[i] == 0 and nb_trusted_by[i] == n-1: # not trusting anyone & trusted by everyone
30                return i
31
32        return -1

Python-Specific Learnings

  1. List Initialisation Use a list to track trust scores for each person.
  2. Loop Structure Iterate over trust pairs to adjust scores.
  3. Return Value Check for the person with a trust score of n-1.

Edge Cases

  • Single person with no trust relationships → returns 1
  • No person satisfies the judge conditions → returns -1

Complexity

  • Time: $O(T + n)$, where $T$ is the length of the trust list
  • Space: $O(n)$

Why This Works

  • The judge has a trust score of n-1 because= they are trusted by everyone else and trust no one.

3432. Count Partitions with Even Sum Difference

Problem: Count partitions where the difference between the sum of left and right partitions is even.

Learning Journey

  1. Initial approach with itertools:
1# Using accumulate for prefix sums
2prefix_sum_from_left = list(itertools.accumulate(nums))
3prefix_sum_from_right = list(itertools.accumulate(reversed(nums)))
4prefix_sum_from_right.reverse()

Key Insight: While clean, straightforward, this creates 2 extra arrays (O(n) space) and reverses twice

First naive solution:

 1class Solution:
 2    def countPartitions(self, nums: List[int]) -> int:
 3
 4
 5        # prefix_sum_from_left = []
 6        prefix_sum_from_left = list(itertools.accumulate(nums))
 7        prefix_sum_from_right = list(itertools.accumulate(reversed(nums)))
 8        prefix_sum_from_right.reverse()
 9
10        # print("prefix_sum_from_left", prefix_sum_from_left)
11        # print("prefix_sum_from_right", prefix_sum_from_right)
12
13        count = 0
14        for i in range(1, len(nums)):
15            print("i", i)
16            if (prefix_sum_from_left[i-1] - prefix_sum_from_right[i]) % 2 == 0:
17                count += 1
18
19        return count
  1. Optimised approach:
1total_sum = sum(nums)  # Single O(n) operation
2for num in nums[:-1]:  # O(n) iteration
3    prefix_sum += num
4    suffix_sum = total_sum - prefix_sum  # O(1) calculation

Optimised solution:

 1class Solution:
 2    def countPartitions(self, nums: List[int]) -> int:
 3        # Calculate total sum to avoid computing it multiple times.
 4        total_sum = sum(nums)
 5        print("total_sum", total_sum)
 6
 7        prefix_sum = 0
 8        count = 0
 9
10        # We only need to check up to n-1 for partitioning.
11        # for i in range(0, len(nums)-1):
12        for i in nums[:-1]:
13            prefix_sum += nums[i]
14            current_oposite = total_sum - prefix_sum
15            # print("prefix_sum", prefix_sum)
16            # print("current_oposite", current_oposite)
17
18            # Check if the difference between left and right partition sums is even.
19            if ((prefix_sum - current_oposite) % 2) == 0:
20                count += 1
21
22        return count

Optimisation: Reduced space complexity from $O(n)$ → $O(1)$ by calculating suffix on the fly

Complexity Deep Dive

ApproachTimeSpaceReal-World Impact
InitialO(n)O(n)2x memory usage for large datasets
OptimisedO(n)O(1)Handles 1M+ elements efficiently

Why This Matters in Interviews

  • Shows progression from “make it work” → “make it efficient”
  • Demonstrates understanding of space-time tradeoffs
  • Highlights ability to optimize mathematical operations

Common Follow-Up Questions

  1. “How would you handle negative numbers in the array?”
    • Current solution works (sum properties hold), but test edge cases
  2. “What if the array contains zeros?”
    • Valid partition points still work, need to verify with examples
  3. “Can you solve this with constant space without calculating total sum first?”
    • Challenge: Requires different mathematical approach

Related Interview Topics

  • Prefix sum variations (2D arrays, circular arrays)
  • Space-time complexity tradeoff decisions
  • Mathematical pattern recognition (even/odd properties)
  • Edge case identification (empty arrays, single elements)

Similar Problems


1848. Minimum Distance to the Target Element

Problem: Find minimum absolute difference between indices containing target value and given start index.

 1class Solution:
 2    def getMinDistance(self, nums: List[int], target: int, start: int) -> int:
 3        if nums[start] == target:
 4            return 0
 5
 6        min_dist = float('inf')
 7
 8        for i, num in enumerate(nums):
 9            if nums[i] == target:
10                min_dist = min(min_dist, abs(i - start))
11
12        return min_dist

Key Learnings:

  1. enumerate(): Efficiently track both index and value during iteration
    • More Pythonic than range(len(nums))
    • Clearer intent when needing both index and value
  2. min(): Built-in function for maintaining minimum value
    • More efficient than manual comparisons
    • Handles edge cases implicitly
  3. float('inf'): Initialize with infinite value pattern
    • Common algorithm technique for minimization problems
    • Guarantees first valid value will replace it

Complexity:

  • Time: $O(n)$ - Single pass through array
  • Space: $O(1)$ - Constant extra space

88. Merge Sorted Array

Problem: Merge nums2 into nums1 in-place while maintaining sorted order.

Key Insight Utilise 3-pointer technique starting from the end of both arrays to avoid overwriting nums1 values.

Python Implementation

 1class Solution:
 2    def merge(self, nums1: List[int], m: int, nums2: List[int], n: int) -> None:
 3        """
 4        Do not return anything, modify nums1 in-place instead.
 5        """
 6
 7        pointer_nums1 = m - 1
 8        pointer_nums2 = n - 1
 9        pointer_placement = m + n - 1
10
11        while pointer_nums1 >= 0 and pointer_nums2 >= 0:
12            if nums1[pointer_nums1] > nums2[pointer_nums2]:
13                nums1[pointer_placement] = nums1[pointer_nums1]
14                pointer_nums1 -= 1
15            else:
16                nums1[pointer_placement] = nums2[pointer_nums2]
17                pointer_nums2 -= 1
18
19            pointer_placement -= 1
20
21        nums1[: pointer_nums2 + 1] = nums2[: pointer_nums2 + 1]
22        qwe

qwe

Python-Specific Learnings

  1. In-place Modification Directly modifies nums1 without extra space
  2. Pointer Manipulation Negative indices work naturally in Python for reverse traversal
  3. Slice Assignment nums1[:p2 + 1] = ... efficiently copies remaining elements -> nums1[: pointer_nums2 + 1] = nums2[: pointer_nums2 + 1]

Complexity

  • Time: $O(m + n)$ - Single pass through both arrays
  • Space: $O(1)$ - No additional data structures used


🎯 to be added more …


LeetCode Grind Plan 🔥

  1. learn the basics of python3 such as
    1. syntax
    2. data types
    3. builtin functions

Python note

  • Uses snake_case
  • PascalCase for class names
  • """ ... """ to do multiple lines comments like /* */ in js
  • Use explicit is for None comparisons: if x is None
     1# 🚨 Dangerous (might give false positives)
     2def process_data(data=[]):
     3    if not data:  # Could be None, empty list, 0, False, etc
     4        print("No data received")
     5
     6# ✅ Explicit check
     7def process_data(data=None):
     8    if data is None:  # Only triggers for None
     9        data = []
    10    # process data...
    
  • Prefer list comprehensions over loops where readable
     1# Traditional loop
     2squares = []
     3for num in range(10):
     4    if num % 2 == 0:
     5        squares.append(num ** 2)
     6
     7# List comprehension (same result)
     8squares = [num ** 2 for num in range(10) if num % 2 == 0]
     9
    10# Nested example (still readable)
    11matrix = [[1,2], [3,4], [5,6]]
    12flattened = [num for row in matrix for num in row]
    

Set

1# simply just
2# Create a set
3set = set()
4
5# then you can directly use the existing array to a set like
6list = [1,2,3]
7set = set(list)
8# then you can use the set to do some operations
9print(set)

Array

Map

1# Create a dictionary

below are outdated notes, to be refined later

Variables

1print()
2print("Hello", "World")
3# "Hello World"
4print("Hello", "World", sep="")
5# "HelloWorld"
1type()
1// # this forces the output to be integer

Type Conversion: The process of converting one data type to another data type is called type conversion.

In Python, we can perform two types of type conversion.

  1. Implicit Type Conversion - Here, Python automatically converts one data type to another in order to avoid data loss.

    e.g. 1 * 1.23 = 1.23 as there is no data loss

  2. Explicit Type Conversion - Here, the user can convert the data type of a variable to the required data type by using the in-built functions int(), float(), str(), etc.

e.g. "Hello " + str(123)

Data Structures

List

1list = [0,1,2,3]
2len(list)
3# 4
4min(list)
5# 0
6max(list)
7# 3

first N items in list

1print(list[0:3]) # Exclusive 3 - incl:excl
2# [0, 1, 2]

Last item

1print(list[-1])

Remove last and return

1list.pop()
2# 3
3print(list)
4# [0,1,2]

Add to last

1list.append(4)
2print(list)
3# [0,1,2,4]

Tuples

1storage = (32,64,128,256)
2print(storage)
3# (32, 64, 128, 256)
1print(storage[1])
2# 64

Tuples are immutable

Dictionary (Map)

1# creating a dictionary
2attributes = {
3    'Brand': 'Apple',
4    'RAM (in GB)': 4,
5    'Storage (in GB)': 128,
6    'Price (in $)': 800
7    }
8print(attributes)
9# {'Brand': 'Apple', 'RAM (in GB)': 4, 'Storage (in GB)': 128, 'Price (in $)': 800}
1type(attributes)
2# dict
 1# creating a dictionary for storing data.
 2products = {
 3    'Brand': brand_list,
 4    'RAM (in GB)': ram_list,
 5    'Storage (in GB)': storage_list,
 6    'Price (in $)': price_list
 7    }
 8
 9print(products)
10# {'Brand': ['Apple', 'Samsung', 'LG', 'Motorola'], 'RAM (in GB)': [4, 12, 8, 8], 'Storage (in GB)': [128, 128, 64, 128], 'Price (in $)': [900, 899, 600, 1000]}
1# keys of a dictionary
2keys = products.keys()
3print('The keys of the dictionary are :\n',keys)
4# ['Brand', 'RAM (in GB)', 'Storage (in GB)', 'Price (in $)']
1# values of a dictionary
2values = products.values()
3print('The values of the dictionary are :\n', values)
4# [['Apple', 'Samsung', 'LG', 'Motorola'], [4, 12, 8, 8], [128, 128, 64, 128], [900, 899, 600, 1000]]

update({key: value})

1dictionary={1: "USA", 2: "India", 3: "China"}
2dictionary.update({3:"Japan"})
3print(dictionary)
4# {1: 'USA', 2: 'India', 3: 'Japan'}

pop(key)

1dictionary={1:"USA", 2:"India", 3:"China"}
2dictionary.pop(2)
3print(dictionary)
4# {1: 'USA', 3: 'China'}

Conditional Statements

… nth much

1price = 900
2# define the budget price
3budget = int(input('Enter your budget(in dollars): '))
4
5# if-else statement
6if price <= budget:
7  print('Congrats! You can buy the Iphone')
8else:
9  print('Sorry! The mobile price is more than your budget')

Looping Statements

1print(range(6))
2# range(0, 6)
1print(list(range(6)))
2# [0, 1, 2, 3, 4, 5]
1print(list(range(2,6)))
2# [2, 3, 4, 5]
1print(list(range(6, 14, 2))) # Iterating by 2
2# [6, 8, 10, 12]

List Comprehensions

Example 1: from:

1discounted_price_list=[]
2
3for x in price_list:
4  discounted_price = x - (x*(5/100))
5  discounted_price_list.append(discounted_price)
6
7print(discounted_price_list)

to:

1discounted_price_list = [x - (x*(5/100)) for x in price_list]
2print(discounted_price_list)

Example 2: from:

1within_budget = []
2
3for x in discounted_price_list:
4  if x <= budget:
5    within_budget.append('Yes')
6  else:
7    within_budget.append('No')
8
9print(within_budget)

to:

1# asking for customer's budget
2budget = int(input('Enter your budget(in dollars): '))
3
4# creating a list of Yes/No based on budget and discounted prices
5within_budget = ['Yes' if x <= budget else 'No' for x in discounted_price_list]
6print(within_budget)

Functions

lambda functions

1dis_price_lambda = lambda discount : 900 - ( 900 * (discount / 100) )
2# call the function with discount = 10%
3dis_price_lambda(10)
4# 810.0

Wow …

1def say(message, times):
2    print(message*times)
3say("How are you", 2)
4# How are youHow are you
1(lambda x: (x+2)*5/2)(4)
2# 15.0

Due to the division operation in the expression, which produces a floating-point result in Python 3. Use // instead, if you want to perform floor division.

*args and **kwargs

from:

 1def total_amount(price1, price2, price3, price4, price5):
 2    """
 3    This function takes the price of five phones ordered
 4    and returns the total order amount.
 5    """
 6    # computing the total order amount
 7    total = price1 + price2 + price3 + price4 + price5
 8
 9    # return the total amount
10    return total
11
12print('Total order amount:', total_amount(700, 599, 650, 900, 820))
13# Total order amount: 3669

to:

 1def total_amount(*args): # can be renamed to *prices
 2    """
 3    This function takes the prices of phones ordered
 4    and returns the total order amount.
 5    """
 6    total = 0
 7    # computing the total order amount
 8    for arg in args:
 9        total += arg
10
11    # return the total amount
12    return total
13
14print('Total order amount:', total_amount(700, 599, 650, 900, 820))
15# Total order amount: 3669
16print('Total order amount:', total_amount(700, 599, 650, 900, 820, 630, 520, 799, 999, 840))
17# Total order amount: 7457

like a general param in Elixir

 1def customer_net_spend(*prices, discount=0.0, **kwargs):
 2    """
 3    This function takes the prices of phones ordered,
 4    the discount percentage, and any other cost additions/subtractions,
 5    and returns the customer's net spend on the order.
 6    """
 7    total = 0
 8    # computing the total order amount
 9    for price in prices:
10        total += price
11
12    total_discounted_price = total - discount*total
13
14    net_spend = total_discounted_price - kwargs['cashback']
15
16    # return the total amount
17    return net_spend
18
19additionals = {'cashback': 5}
20print('Customer net spend (during last day of festive season):', customer_net_spend(700, 599, 650, discount=0.05, **additionals))
21# Customer net spend (during last day of festive season): 1846.55

kwargs is like a %{key: value} in Elixir

 1def order_summary(*prices, **additionals):
 2    """
 3    This function takes the prices of phones ordered
 4    and any other cost additions/subtractions,
 5    and returns the total amount, net spend,
 6    and rewards points earned for the order.
 7    """
 8    total = 0
 9    # computing the total order amount
10    for price in prices:
11        total += price
12
13    net_spend = total - additionals['discount']*total - additionals['cashback']
14
15    if total >= 10000:
16        reward_points = 300
17    elif total >= 5000:
18        reward_points = 200
19    elif total >= 2000:
20        reward_points = 100
21    else:
22        reward_points = 0
23
24    # return the total amount
25    return total, net_spend, reward_points # Is going to return as tuple
26
27additionals = {'discount':0.05, 'cashback': 5}
28ta, ns, rp = order_summary(700, 599, 750, **additionals)
29print('Customer Order Summary:\n', '\nTotal Amount:', ta, '\nTotal Discounted Amount:', ns, '\nReward Points Earned:', rp)
30
31# Customer Order Summary:
32#
33# Total Amount: 2049
34# Total Discounted Amount: 1941.55
35# Reward Points Earned: 100

Invalid Syntax

1def my_function(a, b, **kwargs, *args):
2    return a+b
3my_function(5,6)

because *args (for variable-length positional arguments) must be placed before **kwargs (for variable-length keyword arguments).

 1def my_function(a, b, *args, **kwargs):
 2    print("a:", a)
 3    print("b:", b)
 4    print("args:", args)
 5    print("kwargs:", kwargs)
 6
 7my_function(1, 2, 3, 4, 5, x=6, y=7)
 8# a: 1
 9# b: 2
10# args: (3, 4, 5)
11# kwargs: {'x': 6, 'y': 7}
1def fun(A, B=30):
2    return A + B
3
4# A is a positional argument and B is a keyword argument

Some findings

1list_mul = ['2','2','2']
2list_mul*2

Comparison

AspectPythonJavaScript
Syntax & Code StructureClean, minimal syntax: Uses indentation and colons to define code blocks instead of curly braces, leading to cleaner and more readable code (Why I moved from JavaScript to Python for LeetCode - DEV Community). No semicolons are required and there is less boilerplate (e.g. no parentheses around if conditions) (Why I moved from JavaScript to Python for LeetCode - DEV Community). Python also offers syntactic sugar like list comprehensions, multiple assignment, and tuple unpacking that make code more concise and expressive (Why I moved from JavaScript to Python for LeetCode - DEV Community).C-style syntax: Uses curly braces { } to denote code blocks and typically uses semicolons to terminate statements (though semicolons are optional in modern JS) (Why I moved from JavaScript to Python for LeetCode - DEV Community). This results in a bit more verbose structure and punctuation compared to Python (Why I moved from JavaScript to Python for LeetCode - DEV Community). JavaScript’s syntax is flexible (e.g. arrow functions, object literals, destructuring) but generally requires more symbols, which can make simple logic appear slightly more cluttered than Python.
Pros (Coding Interviews)Readable and quick to write: Python’s simple, English-like syntax lets you implement solutions quickly – it often feels like writing pseudocode (Why JavaScript is actually a great LeetCode/Interview language - DEV Community) (Which language is best for interviews?). It has a rich set of built-in functions and data structures (lists, dictionaries, sets, etc.) that simplify common tasks without extra code (Which language is best for interviews?). Python is widely used on LeetCode and in interviews, so many interviewers are familiar with it, and there are plenty of solution resources available in Python.Versatile and fast: JavaScript works for both frontend and backend (Node.js), so using it in interviews can be advantageous if you’re applying for web development roles (Which language is best for interviews?). Its syntax is relatively simple (no explicit types) and far less verbose than Java or C++, which means you can still code and iterate quickly under time pressure. The V8 engine gives JavaScript very high execution speed, so performance is rarely a bottleneck for algorithmic problems (Why JavaScript is actually a great LeetCode/Interview language - DEV Community). Additionally, JavaScript has handy built-in methods (like Array.prototype.map, filter, reduce) that can make code succinct and show off elegant problem-solving when used appropriately.
Cons (Coding Interviews)Performance and speed limits: Python’s runtime speed is slower than some other languages, which can lead to timeouts on extremely large test cases if the solution isn’t optimal (Which language is best for interviews?) (Why JavaScript is actually a great LeetCode/Interview language - DEV Community). It also has higher memory overhead for data structures (e.g. a list or dict may use more memory than a similar structure in C/C++ or JS) (Node.js vs Python: Selecting the Ideal Backend Tech for 2024). Additionally, Python’s significant whitespace (indentation) means a simple indent mistake can cause a syntax error – this is easy to fix with practice, but it’s a gotcha for those not used to it.Limited data structures & subtle quirks: JavaScript has fewer native data structures for algorithms – for example, it lacks a built-in heap/priority queue, so you might need to implement one manually if needed (Why JavaScript is actually a great LeetCode/Interview language - DEV Community) (Which language is best for interviews?). Some language quirks can also cause bugs: JavaScript’s loose typing and type coercion (e.g. "5" + 2 vs "5" - 2) can lead to unexpected behavior if you’re not careful. And unlike Python, certain errors won’t stop execution (e.g. out-of-bounds array access just yields undefined instead of throwing an error), so logic bugs might not be immediately obvious. Historically, algorithm communities had fewer JS solutions (though this is improving), meaning slightly less community guidance for tricky problems compared to Python.
Code Readability & ConcisenessHighly readable: Python’s enforced indentation and uncluttered syntax make code easy to follow. It generally requires fewer lines to solve a problem than JavaScript, thanks to features like list comprehensions and the lack of extra symbols (Why I moved from JavaScript to Python for LeetCode - DEV Community). In practice, Python code is often considered more concise and closer to pseudocode, which helps others (including interviewers) understand your solution quickly (Python Vs Javascript: What are the Differences? in 2025).Fairly readable (with more syntax): JavaScript code includes braces and semicolons, which add some visual noise. However, its syntax is familiar to many developers and is still relatively succinct compared to languages like Java. Modern ES6+ features (arrow functions, destructuring, etc.) have improved JavaScript’s conciseness, but Python’s syntax is typically shorter for equivalent logic (Python Vs Javascript: What are the Differences? in 2025). Clear formatting and naming in JS are important to approach Python’s level of readability.
Built-in Data Structures & Libraries“Batteries included”: Python offers a wide range of built-in data structures – lists, dictionaries (hash maps), sets, tuples – each optimized for different use cases (Why I moved from JavaScript to Python for LeetCode - DEV Community). It also has modules like collections (providing deque, Counter, etc.) and heapq for heaps, which are extremely handy for interview problems involving queues, stacks, or priority queues. Many algorithms can be implemented using Python’s standard library (e.g. sorting with sorted(), binary search with bisect), reducing the amount of code you must write. This richness means Python often has a ready-made tool for common interview tasks (Why I moved from JavaScript to Python for LeetCode - DEV Community) (Why I moved from JavaScript to Python for LeetCode - DEV Community).Basic structures only: JavaScript historically had just arrays (for lists) and objects (for key-value maps) as built-ins (Why I moved from JavaScript to Python for LeetCode - DEV Community). ES6 added Map and Set classes for dictionaries and sets, but there is still no native deque or heap structure (Why JavaScript is actually a great LeetCode/Interview language - DEV Community). You can use arrays to simulate stacks/queues (with push/pop and shift), but operations like removing from the front of an array are not as efficient as Python’s collections.deque (Why I moved from JavaScript to Python for LeetCode - DEV Community). Similarly, to get a priority queue, you would have to use an array and sort it or implement a heap manually. JavaScript’s standard library has fewer algorithm-specific utilities, so interview solutions may require writing more helper code from scratch (libraries exist but usually aren’t available in coding test environments).
Execution Speed & Memory UsageSlower execution, higher memory: Python is generally slower at runtime because it’s interpreted (CPython has no JIT). For very large inputs or heavy computations, a Python solution might run close to the time limit – there are anecdotes of hitting timeouts in Python even with optimal algorithms (Why JavaScript is actually a great LeetCode/Interview language - DEV Community). In contrast, JavaScript’s JIT-compiled engine often runs the same algorithm faster. Python’s structures also tend to use more memory (each object has overhead), so a large list/dict can consume more memory than an equivalent structure in JS (Node.js vs Python: Selecting the Ideal Backend Tech for 2024). The upside is that Python’s high-level operations (big integers, slicing, etc.) are handled for you (convenience at some cost). In most interview problems, if your algorithmic complexity is good, Python is fast enough, but it’s something to keep in mind for edge cases.Fast JIT execution, lower memory: JavaScript executes very fast under modern engines – its JIT compilation and optimizations let it approach the speed of lower-level languages like Java/C++ (Why JavaScript is actually a great LeetCode/Interview language - DEV Community). This means if you write an efficient algorithm in JS, you’re unlikely to hit performance issues on coding platforms. Memory usage for JavaScript’s data types is generally lower than Python’s for the same workload, since primitive types (numbers, booleans) are lightweight. Both Python and JS have garbage collection, so memory is managed for you, but JS’s overall memory footprint for a large data structure tends to be a bit smaller (Node.js vs Python: Selecting the Ideal Backend Tech for 2024). In short, JavaScript provides better raw performance, which can be a confidence boost when handling big inputs in interviews.
Ecosystem & Job Market RelevanceVersatile ecosystem: Python has a massive ecosystem in areas like web backends (Django/Flask), data science, machine learning, automation, etc. It’s often ranked just behind JavaScript in overall popularity, reflecting its broad use across industries (Programming languages with the highest labor demand 2024 : r/AskProgramming). In interview practice, Python is extremely common – many competitive programming and LeetCode discussions use Python, so a wealth of learning resources is available. For job hunting, knowing Python opens up roles in AI/ML, data analysis, scientific computing, and backend development (Python vs JavaScript: What to Choose in 2024 - Monarch Innovation). Many companies (especially in those domains) allow or encourage Python in interviews. (For front-end roles, Python is less directly relevant, but those interviews might focus on system design or algorithms where Python can still be used.)Dominant for web: JavaScript is arguably the most in-demand programming language today, powering the vast majority of web applications (Programming languages with the highest labor demand 2024 : r/AskProgramming). Its ecosystem (Node.js, NPM, and frameworks like React/Angular) makes it indispensable for front-end and full-stack development (Python vs JavaScript: What to Choose in 2024 - Monarch Innovation). In coding interviews, JavaScript is commonly used if you’re targeting a front-end or full-stack position, and companies hiring for those roles will expect proficiency in it. While historically algorithm interview communities were dominated by Python/Java/C++, JavaScript has become very popular as more candidates from web backgrounds use it. Job-market wise, JavaScript skills are highly marketable – it’s often said to be “absolutely dominating” job postings, with Python in second place (Programming languages with the highest labor demand 2024 : r/AskProgramming). So choosing JS for interviews is wise if it aligns with the job’s tech stack.
Debugging & Error HandlingClear errors: Python tends to fail fast and loud. It is strongly typed at runtime, so invalid operations (like adding incompatible types or accessing an out-of-range index) immediately raise exceptions with informative tracebacks (Why are using exceptions more acceptable in python than javascript - Stack Overflow). This helps with debugging during interviews, since mistakes are caught early rather than silently producing wrong results. Python uses try/except blocks for error handling; exceptions are a normal part of control flow for unusual conditions (e.g. catching a KeyError instead of checking existence every time). Overall, Python’s error messages are usually clear (pointing out the exact issue and location), which makes it straightforward to fix bugs in your code.Silent failures possible: JavaScript uses try/catch for exceptions similarly, but many errors won’t throw exceptions by default. The language often “glosses over” issues – for example, using a non-existent array index just gives undefined and keeps running, rather than throwing an error (Why are using exceptions more acceptable in python than javascript - Stack Overflow). This means a bug can fail silently, and you have to carefully watch for unexpected undefined/NaN values. Type coercion can also cause subtle issues without any error (e.g. "5" * 2 becomes 10 in JS, whereas in Python "5" * 2 would throw a TypeError). In practice, debugging JavaScript might involve more manual checks or console logs to pinpoint logic errors. On the plus side, modern debuggers (browser DevTools, Node.js inspector) are very powerful for stepping through code when you have that environment. In interview platforms, you’ll primarily rely on test cases, so in JS it’s important to add your own validations or use strict equality (===) to avoid tricky coercion bugs.
Transitioning from JavaScript to PythonAdapting to Python: If you’re moving from JS to Python, focus on Python’s idioms and differences. Embrace whitespace – Python uses indentation instead of {} braces, and a missing colon or wrong indent will cause errors, so practice writing neatly indented code. Get used to Python syntax for common constructs (e.g. for x in list instead of C-style index loops, and/or instead of &&/`

JavaScript vs Python Core Concepts

ConceptJavaScript ExamplePython Example & Notes
Variableslet x = 10;
const y = 20;
x = 10 (dynamic typing)
y = 20 (reassignable)
Constantsconst PI = 3.14;PI = 3.14 (by convention)
from math import pi (built-in constants)
Functionsfunction add(a, b) { return a + b; }def add(a, b): return a + b
Indentation defines blocks
Data TypesDynamic typingDynamic typing:
s = "text"
n = 3.14 (type hints optional: n: float = 3.14)
Collectionsconst arr = [1,2];
const obj = {key:1};
arr = [1,2] (list)
d = {"key": 1} (dict)
t = (1,2) (tuple)
s = {1,2} (set)
Zero Valuesundefined, nullNone (single null-like value)
No undefined concept
Error Handlingtry/catchtry/except
EAFP: “Easier to ask forgiveness than permission”
ConcurrencyPromise, async/awaitasyncio, async/await
threading, multiprocessing
MemoryAutomatic GCAutomatic GC
Reference counting + cycle detection
Buildnode script.jspython script.py
Interpreted, no compilation step
comments powered by Disqus