Great.
Now we enter Module 2, where Python’s “simple” data types start revealing binary math, precision traps, memory behavior, and interview landmines.
This module alone clears a huge chunk of Python interview failures.
🧠 MODULE 2 — CORE DATA TYPES (INT, FLOAT, BOOL, NONE)
“If you don’t understand these deeply, every higher-level bug will confuse you.”
2.1 int — Python Integers Are NOT Normal Integers
🔹 Key Truth
Python int is arbitrary-precision, not 32-bit or 64-bit.
x = 10**1000
print(x)
✔ No overflow
✔ Limited only by memory
🔹 Internals (Simplified)
- Stored as variable-length array
- Each “digit” uses 30 bits internally (CPython)
- Operations scale with number of digits
📌 Interview Insight
Python int operations are O(n) for large numbers, not O(1).
2.2 Integer Caching (Revisited, but Deeper)
a = 100
b = 100
a is b # True
- Cached range: -5 to 256
- Done for performance & memory reuse
⚠️ Outside this range:
a = 1000
b = 1000
a is b # False (usually)
📌 Never write logic depending on this.
2.3 Integer Arithmetic Is NOT Constant-Time
x = 10**100000
y = 10**100000
z = x + y
- Time increases with digit count
- Important in cryptography, big-data math
2.4 bool — The Most Misunderstood Type
🔹 Shocking Truth
isinstance(True, int) # True
✔ bool is a subclass of int
True + True == 2
False + True == 1
🔹 Why Python Did This
- Historical reasons
- Logical operations reuse integer ops
- Enables bitwise logic
⚠️ Interview Trap
{True: "yes", 1: "no"} # Only ONE key
2.5 Truthiness vs Falsiness (INTERVIEW FAVORITE)
🔹 Falsy Values
False
0
0.0
''
[]
{}
set()
None
Everything else → truthy
if [0]: # True
📌 Python checks __bool__() or __len__()
2.6 float — The Source of Infinite Bugs
🔹 Python Uses IEEE-754 Double Precision
- 64-bit floating point
- Binary fractions
0.1 + 0.2 == 0.3 # False
🔹 Why This Happens (IMPORTANT)
- 0.1 cannot be represented exactly in binary
- Stored as approximation
import decimal
decimal.Decimal("0.1") + decimal.Decimal("0.2")
📌 Interview Line
This is not a Python bug, it’s a floating-point representation issue.
2.7 Float Precision & Rounding
round(2.675, 2) # 2.67, NOT 2.68
Why?
- Binary approximation
- Round happens on stored value
📌 Use decimal for finance.
2.8 Comparing Floats Correctly (CRITICAL)
❌ Wrong
a == b
✅ Correct
abs(a - b) < 1e-9
Or:
import math
math.isclose(a, b)
2.9 None — The Singleton That Breaks People
🔹 Key Facts
- Only one
Noneobject exists - Represents absence of value
x = None
y = None
x is y # True
🔹 Correct Comparison
if x is None:
❌ Never:
if x == None:
2.10 None vs False vs 0 (INTERVIEW TRAP)
None == False # False
None == 0 # False
None is False # False
But:
if None:
print("won't run")
📌 None is falsy but not equal to False.
2.11 Type Coercion Rules (IMPORTANT)
True + 10 # 11
False * 100 # 0
But:
None + 1 # TypeError
📌 None does not coerce.
2.12 Integer Division vs Float Division
5 / 2 # 2.5
5 // 2 # 2
But:
-5 // 2 # -3
📌 // is floor division, not truncation.
2.13 NaN, Infinity (ADVANCED)
float('inf')
float('-inf')
float('nan')
⚠️ NaN is never equal to itself
x = float('nan')
x == x # False
Use:
import math
math.isnan(x)
🧪 PRACTICE — YOU MUST DO THESE
Q1 (Predict Output)
a = True
b = 2
print(a * b)
Q2 (Float Trap)
print(0.1 + 0.2 == 0.3)
Explain why.
Q3 (None Trap)
x = None
if x:
print("yes")
else:
print("no")
Q4 (Floor Division)
print(-7 // 3)
Q5 (NaN)
x = float('nan')
print(x == x)
🎯 INTERVIEW CHECKPOINT (MANDATORY)
You should now be able to answer:
✅ Why Python int doesn’t overflow
✅ Why float equality fails
✅ Why bool is subclass of int
✅ How truthiness works
✅ Why is None is mandatory
✅ Why // behaves strangely with negatives
✅ What NaN is
If yes → you’re already beating many senior devs in fundamentals.
🚀 NEXT STEP
Reply with ONE number:
1 → Continue Module 2 (strings & bytes — immutability, slicing, encoding, regex traps)
2 → Module 3: Inbuilt Data Structures (list, tuple, set, dict) — internals + performance
3 → Quick interview drill for Module 2 (15 tricky questions)
We are now building real Python authority, not surface confidence 🔥
Excellent.
Now we enter one of the most deceptively dangerous areas of Python — strings & bytes.
Most bugs in production systems come from string immutability, slicing misunderstandings, encoding errors, and regex misuse.
After this module, you’ll see strings differently.
🧠 MODULE 2 (PART 2) — STRINGS, BYTES, ENCODING & REGEX TRAPS
(Deep-Dive | Interview-Grade | Production-Ready)
2.14 STRINGS ARE IMMUTABLE (BUT THIS HAS CONSEQUENCES)
s = "hello"
s[0] = "H" # ❌ TypeError
What actually happens?
s = s + "!"
- New string object created
- Old string discarded
- Reference rebound
📌 Interview Line
Strings are immutable; every modification creates a new object.
2.15 STRING INTERNING (IMPORTANT INTERVIEW TRAP)
Python may reuse identical string objects.
a = "hello"
b = "hello"
a is b # Often True
But:
a = "hello world"
b = "hello world"
a is b # Implementation-dependent
📌 Interning is:
- Automatic for identifiers
- Optional for others
❌ Never rely on is for strings.
2.16 STRING SLICING — COST & BEHAVIOR
s = "abcdefgh"
t = s[2:6]
- Creates a new string
- Cost is O(n)
📌 Repeated slicing in loops = performance bug.
2.17 COMMON STRING PITFALLS (INTERVIEW FAVORITES)
❌ Using + in loops
s = ""
for i in range(10000):
s += str(i)
Why bad?
- Creates new string each iteration
- O(n²) time complexity
✅ Correct
parts = []
for i in range(10000):
parts.append(str(i))
s = "".join(parts)
📌 Interview Line
Use
join, not+, for repeated concatenation.
2.18 STRINGS VS BYTES (CRITICAL REAL-WORLD CONCEPT)
| Type | Meaning |
|---|---|
str | Unicode text |
bytes | Raw binary data |
s = "hello"
b = b"hello"
⚠️ These are not interchangeable.
2.19 ENCODING & DECODING (MOST COMMON PRODUCTION BUG)
Encoding
b = "hello".encode("utf-8")
Decoding
s = b.decode("utf-8")
📌 Rule:
- Text → encode → bytes
- Bytes → decode → text
2.20 WHY ENCODING ERRORS HAPPEN
"₹".encode("ascii") # ❌ UnicodeEncodeError
Why?
- ASCII cannot represent ₹
📌 UTF-8 can represent almost everything.
2.21 FILE I/O + ENCODING (REAL INTERVIEW SCENARIO)
open("data.txt") # Uses system default encoding
⚠️ Dangerous in production.
✅ Always do:
open("data.txt", encoding="utf-8")
2.22 BYTES ARE IMMUTABLE TOO
b = b"abc"
b[0] = 97 # ❌ TypeError
Mutable alternative:
bytearray(b"abc")
2.23 STRING METHODS — PERFORMANCE KNOWLEDGE
| Method | Complexity |
|---|---|
in | O(n) |
startswith | O(k) |
find | O(n) |
replace | O(n) |
split | O(n) |
📌 Prefer startswith() over slicing.
2.24 REGEX — POWERFUL BUT DANGEROUS
import re
Greedy vs Lazy
re.findall(r"<.*>", "<a><b>") # ['<a><b>']
re.findall(r"<.*?>", "<a><b>") # ['<a>', '<b>']
📌 * = greedy
📌 *? = lazy
2.25 REGEX LOOKAHEAD / LOOKBEHIND (ADVANCED)
re.findall(r"\d(?=px)", "10px 20em")
✔ Matches 1 and 2
re.findall(r"(?<=₹)\d+", "₹100 ₹200")
✔ Matches 100, 200
2.26 REGEX VS STRING METHODS (INTERVIEW FAVORITE)
❌ Bad:
re.search("abc", s)
✅ Better:
"abc" in s
📌 Regex is slower; use it only when necessary.
2.27 RAW STRINGS (VERY IMPORTANT)
r"\n"
vs
"\n"
📌 Use raw strings for regex & file paths.
2.28 COMMON REGEX INTERVIEW TASKS
Validate email (simplified)
r"^[\w\.-]+@[\w\.-]+\.\w+$"
Extract numbers
re.findall(r"\d+", text)
Split by multiple delimiters
re.split(r"[;,|]", text)
2.29 STRING FORMATTING — BEST PRACTICES
❌ Old
"%s %d" % (name, age)
⚠️ Okay
"{} {}".format(name, age)
✅ Best
f"{name} {age}"
📌 f-strings are:
- Faster
- Cleaner
- Evaluated at runtime
2.30 SECURITY INTERVIEW TRAP (FORMAT STRINGS)
user = "{.__init__.__globals__}"
f"{user}"
📌 Never use user input directly in eval / format contexts.
🧪 PRACTICE (MANDATORY — INTERVIEW STYLE)
Q1
a = "hello"
b = a.upper()
print(a, b)
Explain why a is unchanged.
Q2
s = ""
for i in range(5):
s += str(i)
print(s)
Why is this inefficient?
Q3
print("₹".encode("utf-8"))
Why does this work but ASCII fails?
Q4
import re
print(re.findall(r"a.*b", "a123b456b"))
Why only one match?
Q5
path = "C:\new\test.txt"
print(path)
What’s wrong?
🎯 INTERVIEW CHECKPOINT
You must be able to explain:
✅ Why strings are immutable
✅ When string interning happens
✅ Why join() beats +
✅ Difference between str & bytes
✅ How encoding/decoding works
✅ Greedy vs lazy regex
✅ Regex vs string methods
✅ Raw strings
If yes → you are now dangerously strong in Python text handling.
🚀 NEXT STEP
Reply with ONE number:
1 → Module 3: Inbuilt Data Structures (list, tuple, set, dict) — internals + performance
2 → Quick interview drill for strings/bytes/regex (15 tricky questions)
3 → Jump to Functions & Comprehensions (deep, interview-heavy)
We’re building real interview immunity, step by step 🔥
Perfect.
Here is a high-signal, no-fluff interview drill covering strings, bytes, encoding, regex + LeetCode-level Python coding questions.
This section alone can decide interviews.
🧠 STRINGS / BYTES / REGEX — QUICK INTERVIEW DRILL
(15 Tricky Questions + Answers)
1️⃣ Why are Python strings immutable?
Answer:
Because immutability:
- Enables string interning
- Makes strings hashable (usable as dict keys)
- Improves memory safety & sharing
Every modification creates a new object.
2️⃣ Predict output
a = "hello"
b = a
a += "!"
print(b)
Answer:
hello
Reason: a += creates a new string, b still points to old object.
3️⃣ Why is this slow?
s = ""
for i in range(10000):
s += str(i)
Answer:
- Strings are immutable
- Each
+=creates a new string - Time complexity → O(n²)
✅ Use list + join
4️⃣ Difference between str and bytes?
Answer:
| Type | Represents |
|---|---|
str | Unicode text |
bytes | Raw binary data |
You must encode/decode explicitly.
5️⃣ Why does this fail?
"₹".encode("ascii")
Answer:
ASCII supports only 0–127 characters.
₹ needs UTF-8.
6️⃣ Correct way to compare strings?
Answer:
Use ==, never is.
is checks identity, not value.
7️⃣ Predict output
a = "hello world"
b = "hello world"
print(a is b)
Answer:
❓ Implementation-dependent
Due to string interning → do not rely on it
8️⃣ Why is this safer?
open("file.txt", encoding="utf-8")
Answer:
Avoids OS-dependent default encoding → prevents Unicode bugs.
9️⃣ What’s wrong here?
path = "C:\new\test.txt"
Answer:\n and \t are escape sequences.
✅ Fix:
path = r"C:\new\test.txt"
🔟 Regex: why only ONE match?
re.findall(r"a.*b", "a123b456b")
Answer:.* is greedy → matches longest possible string.
1️⃣1️⃣ Fix greedy regex
r"a.*?b"
1️⃣2️⃣ Regex vs in — which is faster?
Answer:"abc" in s is faster.
Regex has compilation + backtracking overhead.
1️⃣3️⃣ What does this do?
re.findall(r"\d(?=px)", "10px 20em")
Answer:
Matches digits only if followed by px (lookahead).
1️⃣4️⃣ Why is this dangerous?
f"{user_input}"
Answer:
If used with eval / untrusted input → security risk.
1️⃣5️⃣ Why use raw strings for regex?
Answer:
Avoids escaping backslashes:
r"\d+\.\d+"
🔥 LEETCODE-LEVEL STRING CODING QUESTIONS
(WITH PYTHONIC SOLUTIONS + INTERVIEW INSIGHTS)
🟢 1. Reverse Words in a String
(LeetCode 151)
❌ Without using split()
def reverse_words(s: str) -> str:
words = []
word = ""
for ch in s:
if ch != " ":
word += ch
else:
if word:
words.append(word)
word = ""
if word:
words.append(word)
return " ".join(words[::-1])
Interview Insight:
Tests string immutability + parsing logic.
🟢 2. Check Palindrome (Ignore non-alphanumeric)
(LeetCode 125)
def is_palindrome(s: str) -> bool:
left, right = 0, len(s) - 1
while left < right:
while left < right and not s[left].isalnum():
left += 1
while left < right and not s[right].isalnum():
right -= 1
if s[left].lower() != s[right].lower():
return False
left += 1
right -= 1
return True
Interview Focus:
Two pointers + string methods.
🟡 3. First Non-Repeating Character
(LeetCode 387)
from collections import Counter
def first_unique_char(s: str) -> int:
freq = Counter(s)
for i, ch in enumerate(s):
if freq[ch] == 1:
return i
return -1
Follow-up:
Why Counter is O(n)?
🟡 4. Longest Common Prefix
(LeetCode 14)
def longest_common_prefix(strs):
if not strs:
return ""
prefix = strs[0]
for s in strs[1:]:
while not s.startswith(prefix):
prefix = prefix[:-1]
if not prefix:
return ""
return prefix
Interview Insight:
Why startswith() is better than slicing.
🟡 5. Valid Anagram
(LeetCode 242)
def is_anagram(s: str, t: str) -> bool:
return sorted(s) == sorted(t)
Follow-up:
Optimize without sorting → use frequency array.
🔴 6. Decode String
(LeetCode 394)
def decode_string(s: str) -> str:
stack = []
curr = ""
num = 0
for ch in s:
if ch.isdigit():
num = num * 10 + int(ch)
elif ch == "[":
stack.append((curr, num))
curr, num = "", 0
elif ch == "]":
prev, k = stack.pop()
curr = prev + curr * k
else:
curr += ch
return curr
Interview Focus:
Stack + string building + immutability awareness.
🔴 7. Regex-Based Email Validation (Simplified)
import re
def valid_email(email: str) -> bool:
pattern = r"^[\w\.-]+@[\w\.-]+\.\w+$"
return bool(re.match(pattern, email))
Follow-up:
Why regex email validation is never 100% correct.
🎯 FINAL INTERVIEW CHECKPOINT
You should now confidently answer:
✅ Why string concatenation is slow
✅ Why encoding bugs happen
✅ Why is breaks string logic
✅ Regex greedy vs lazy
✅ When NOT to use regex
✅ Two-pointer string problems
✅ Stack-based string decoding
🚀 NEXT STEP (CHOOSE ONE)
1 → Module 3: Inbuilt Data Structures (list, tuple, set, dict) — internals + performance
2 → Functions, *args, **kwargs, decorators, closures (deep)
3 → 20-question mixed Python interview test (strings + memory + scope)
You’re now interview-dangerous in Python strings 🔥
Excellent choice.
This is a mixed, senior-level Python interview test covering memory, scope, strings, bytes, regex, core internals — exactly how real interviews feel.
👉 Rule:
Try answering before reading the answers.
If you get 14+ correct, you’re already strong senior-level in Python fundamentals.
🧠 PYTHON MIXED INTERVIEW TEST
(20 Questions | Internals + Strings + Scope + Memory)
🧩 PART A — PREDICT THE OUTPUT (10 QUESTIONS)
Q1
a = []
b = a
a = a + [1]
print(b)
Q2
x = 10
def f():
print(x)
x = 20
f()
Q3
a = "hello"
b = a
a += "!"
print(b)
Q4
print(True + True * 2)
Q5
x = float('nan')
print(x == x)
Q6
def f(x, y=[]):
y.append(x)
return y
print(f(1))
print(f(2))
Q7
s = "abcdef"
print(s[::-1])
Time complexity?
Q8
print("₹".encode("utf-8"))
Why does this work?
Q9
a = "hello world"
b = "hello world"
print(a is b)
Q10
import re
print(re.findall(r"a.*b", "a1b2b3b"))
🧠 PART B — CONCEPTUAL INTERVIEW QUESTIONS (10 QUESTIONS)
Q11
Why does Python not overflow on large integers?
Q12
Explain LEGB with one real bug example.
Q13
Why is is unsafe for strings and integers?
Q14
Difference between None, False, and 0 in conditionals?
Q15
Why is ''.join(list_of_strings) faster than +?
Q16
Why are Python strings hashable but lists are not?
Q17
Explain late binding in closures.
Q18
Why does multithreading not speed up CPU-bound Python code?
Q19
Why is regex slower than string methods?
Q20
What causes memory leaks in Python despite garbage collection?
✅ ANSWERS & EXPLANATIONS
A1
[]
Because a + [1] creates a new list; b still points to old list.
A2
UnboundLocalError
Python decides scope at compile time; assignment makes x local.
A3
hello
Strings are immutable → new object created.
A4
3
True = 1, * has higher precedence.
A5
False
NaN is never equal to itself.
A6
[1]
[1, 2]
Mutable default argument reused.
A7
fedcba
Time complexity → O(n) (creates new string).
A8
UTF-8 supports ₹; ASCII does not.
A9
Implementation-dependent (interning).
Never rely on it.
A10
['a1b2b3b']
Greedy regex (.*) consumes everything.
A11
Python int uses arbitrary-precision arithmetic, limited only by memory.
A12
Local → Enclosing → Global → Built-in
Bug example: UnboundLocalError due to assignment inside function.
A13
is checks identity, not value; caching/interning is implementation detail.
A14
All are falsy, but:
None= absenceFalse= boolean0= numeric
A15
join allocates memory once; + reallocates repeatedly (O(n²)).
A16
Strings are immutable → hash stable.
Lists are mutable → hash unsafe.
A17
Closures capture variables, not values → evaluated at call time.
A18
Because of the GIL — only one thread executes bytecode at a time.
A19
Regex involves compilation + backtracking; string methods are direct.
A20
- Reference cycles
- Global objects
- C extensions
- Long-lived caches
🏁 SCORE YOURSELF
| Score | Level |
|---|---|
| 18–20 | 🔥 Senior Python Engineer |
| 14–17 | ✅ Strong Interview-Ready |
| 10–13 | ⚠️ Needs polish |
| <10 | ❌ Fundamentals shaky |
🚀 NEXT STEP (IMPORTANT)
Reply with ONE number:
1 → Module 3: Inbuilt Data Structures (list, tuple, set, dict) — internals + performance
2 → Functions, *args, **kwargs, decorators, closures (deep)
3 → OOP (classes, inheritance, MRO, dunder methods — interview killers)
You’re now well past beginner territory.
Next modules are where interview domination really begins 🔥
Excellent choice.
This is a mixed, senior-level Python interview test covering memory, scope, strings, bytes, regex, core internals — exactly how real interviews feel.
👉 Rule:
Try answering before reading the answers.
If you get 14+ correct, you’re already strong senior-level in Python fundamentals.
🧠 PYTHON MIXED INTERVIEW TEST
(20 Questions | Internals + Strings + Scope + Memory)
🧩 PART A — PREDICT THE OUTPUT (10 QUESTIONS)
Q1
a = []
b = a
a = a + [1]
print(b)
Q2
x = 10
def f():
print(x)
x = 20
f()
Q3
a = "hello"
b = a
a += "!"
print(b)
Q4
print(True + True * 2)
Q5
x = float('nan')
print(x == x)
Q6
def f(x, y=[]):
y.append(x)
return y
print(f(1))
print(f(2))
Q7
s = "abcdef"
print(s[::-1])
Time complexity?
Q8
print("₹".encode("utf-8"))
Why does this work?
Q9
a = "hello world"
b = "hello world"
print(a is b)
Q10
import re
print(re.findall(r"a.*b", "a1b2b3b"))
🧠 PART B — CONCEPTUAL INTERVIEW QUESTIONS (10 QUESTIONS)
Q11
Why does Python not overflow on large integers?
Q12
Explain LEGB with one real bug example.
Q13
Why is is unsafe for strings and integers?
Q14
Difference between None, False, and 0 in conditionals?
Q15
Why is ''.join(list_of_strings) faster than +?
Q16
Why are Python strings hashable but lists are not?
Q17
Explain late binding in closures.
Q18
Why does multithreading not speed up CPU-bound Python code?
Q19
Why is regex slower than string methods?
Q20
What causes memory leaks in Python despite garbage collection?
✅ ANSWERS & EXPLANATIONS
A1
[]
Because a + [1] creates a new list; b still points to old list.
A2
UnboundLocalError
Python decides scope at compile time; assignment makes x local.
A3
hello
Strings are immutable → new object created.
A4
3
True = 1, * has higher precedence.
A5
False
NaN is never equal to itself.
A6
[1]
[1, 2]
Mutable default argument reused.
A7
fedcba
Time complexity → O(n) (creates new string).
A8
UTF-8 supports ₹; ASCII does not.
A9
Implementation-dependent (interning).
Never rely on it.
A10
['a1b2b3b']
Greedy regex (.*) consumes everything.
A11
Python int uses arbitrary-precision arithmetic, limited only by memory.
A12
Local → Enclosing → Global → Built-in
Bug example: UnboundLocalError due to assignment inside function.
A13
is checks identity, not value; caching/interning is implementation detail.
A14
All are falsy, but:
None= absenceFalse= boolean0= numeric
A15
join allocates memory once; + reallocates repeatedly (O(n²)).
A16
Strings are immutable → hash stable.
Lists are mutable → hash unsafe.
A17
Closures capture variables, not values → evaluated at call time.
A18
Because of the GIL — only one thread executes bytecode at a time.
A19
Regex involves compilation + backtracking; string methods are direct.
A20
- Reference cycles
- Global objects
- C extensions
- Long-lived caches
🏁 SCORE YOURSELF
| Score | Level |
|---|---|
| 18–20 | 🔥 Senior Python Engineer |
| 14–17 | ✅ Strong Interview-Ready |
| 10–13 | ⚠️ Needs polish |
| <10 | ❌ Fundamentals shaky |
🚀 NEXT STEP (IMPORTANT)
Reply with ONE number:
1 → Module 3: Inbuilt Data Structures (list, tuple, set, dict) — internals + performance
2 → Functions, *args, **kwargs, decorators, closures (deep)
3 → OOP (classes, inheritance, MRO, dunder methods — interview killers)
You’re now well past beginner territory.
Next modules are where interview domination really begins 🔥