Beginner: foundations · Thinking in Big-O · topic 5 of 61 · 35 min
The real cost of Python and JavaScript built-ins
Explanation
Why built-ins matter
Interview code is short, so most of the work happens inside built-in operations. If you do not know what they cost, you cannot work out the cost of your own code. Many "time limit exceeded" errors on problem sites come from one innocent-looking line inside a loop.
Python lists, dicts and sets
| Operation | Cost | Why |
|---|---|---|
| a[i], a[i] = x, len(a) | O(1) | Jump straight to a position |
| a.append(x), a.pop() | O(1) amortised | Work at the end, no shifting |
| a.insert(0, x), a.pop(0) | O(n) | Every other item shifts by one place |
| x in a, a.index(x), a.count(x), a.remove(x) | O(n) | Scan the list |
| a[i:j] | O(j − i) | Slicing copies the items into a new list |
| sorted(a), a.sort() | O(n log n) | Comparison sorting |
| min(a), max(a), sum(a) | O(n) | Look at every item |
| d[key], key in d, d[key] = v | O(1) average | Hashing (Module 3) |
| x in s, s.add(x), s.remove(x) | O(1) average | Hashing |
| deque.appendleft(x), deque.popleft() | O(1) | A queue built for both ends |
Dict and set operations are O(1) on average because they use hashing: the key is turned into a number that points almost straight at its slot. In rare bad cases many keys collide and it can be slower, but in practice and in interviews treat them as O(1) average.
Strings are immutable
Immutable means a string cannot be changed after it is made. s += "x" therefore builds a brand-new string and copies the old characters into it. In a loop that adds n pieces, the copying can add up to O(n²) work. CPython sometimes optimises this, but the Python style guide (PEP 8) says not to rely on it. The safe pattern: collect the pieces in a list, then call "".join(pieces) once, which is O(total length).
# Slow pattern: may copy the growing string every time
s = ""
for i in range(5):
s += str(i) + ","
# Fast pattern: collect parts, join once
parts = []
for i in range(5):
parts.append(str(i))
print(",".join(parts)) # Output: 0,1,2,3,4JavaScript arrays, Map and Set
JavaScript arrays behave like Python lists. push and pop work at the end and are O(1) amortised. shift and unshift remove or add at the front and move every other item, so treat them as O(n). includes and indexOf scan the array, O(n). The language standard does not promise exact costs, but these are what engines do in practice.
Map and Set are JavaScript's hash map and hash set, with O(1) average get, set, has and delete. A plain object can also work as a map, but its keys are always turned into strings (so 1 and "1" are the same key), and it inherits keys such as "constructor" and "toString". Use Map when keys come from user data or are not strings; Map also remembers insertion order and has a size property.
const seen = new Set();
for (const x of [3, 1, 4, 1]) {
if (seen.has(x)) console.log('repeat:', x);
seen.add(x);
}
console.log([10, 9, 1].sort()); // [1, 10, 9] (compared as strings!)
console.log([10, 9, 1].sort((a, b) => a - b)); // [1, 9, 10]Common mistakes
- x in a_list inside a loop: O(n²) in total. Fix: build a set once, then check x in the_set.
- list.pop(0) or JavaScript shift() in a loop to process a queue. Fix: use collections.deque in Python, or keep a moving "front" index in JavaScript.
- Building strings with += in a long loop. Fix: collect parts in a list and join once.
- Slicing in a loop, such as a[1:] in every step. Fix: use indexes instead of copies.
- Calling sorted() inside a loop. Fix: sort once before the loop, O(n log n) in total.
- Using a JavaScript object as a map for arbitrary keys, or calling sort() on numbers without a compare function. Fix: use Map, and sort numbers with (a, b) => a - b.
Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
The real cost of Python and JavaScript built-ins · 1/8
This lesson shows what the everyday built-ins of Python and JavaScript really cost, so you can spot hidden loops.
Prefer a video by a teacher? Find free videos on “python list dict set time complexity big o of built in operations” on YouTube ↗
In real life: Building a bank statement export
A bank's statement page lets customers download a year of transactions as a CSV file. A first version adds each line to a string with +=; for an account with tens of thousands of transactions the export becomes noticeably slow. Collecting lines in a list and joining them once makes the export linear in the size of the file. The same team keeps the IDs of transactions already exported in a set, so checking for duplicates stays O(1) per line.
rows = [("2026-04-01", "UPI to Swiggy", -350), ("2026-04-02", "Salary", 52000)]
lines = ["date,description,amount"]
for date, desc, amount in rows:
lines.append(f"{date},{desc},{amount}")
print("\n".join(lines))Practice (0/3 done)
The starter builds a string with += and also leaves a trailing comma. Rewrite format_ids(ids) so it collects the parts in a list and joins them ONCE with ",". Each id becomes "ID-" followed by the number. Example: format_ids([1, 2, 3]) returns "ID-1,ID-2,ID-3". An empty list gives "".
Write common_items(a, b) that returns a list of the items of a that also appear in b, in the order they appear in a (keep repeats from a). Make it O(n + m) by turning b into a set first, instead of checking x in b (a list) every time. Example: common_items([1, 2, 2, 3], [2, 3, 4]) returns [2, 2, 3].
Write firstRepeated(arr) in JavaScript. It returns the first element whose SECOND appearance comes earliest while reading left to right, or null if no element repeats. Use a Set so it runs in O(n). Example: firstRepeated([3, 1, 4, 1, 5, 3]) returns 1, because the second 1 (index 3) comes before the second 3 (index 5). Note that 1 and "1" are different values.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- Hash maps and hash setsHashing, two pointers and sliding window
- Queues and dequesStacks, queues and linked lists
- std::map and std::unordered_mapC++ Programming (modern C++ and DSA) · The Standard Template Library (STL)
- List, dict and set comprehensionsPython Programming · Working with data
- Strings: building, comparing and countingArrays and strings
- Dictionaries: look things up by namePython Programming · Lists, tuples, dictionaries and sets
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
Which Python list operation is O(n)?
Answer: a.pop(0)
pop(0) removes the first item, so every other item shifts one place left.
What is the average cost of key in d for a Python dict d?
Answer: O(1)
Dicts use hashing, so membership is O(1) on average.
Why prefer "".join(parts) over s += part in a long loop?
Answer: s += part may copy the whole growing string each time, O(n²) in total
Strings are immutable, so += can create a new string every time; join builds the result once.
In JavaScript, what does [10, 9, 1].sort() return?
Answer: [1, 10, 9]
Without a compare function, sort compares values as strings, and "10" comes before "9".
You need a queue in Python with fast removal from the front. What should you use?
Answer: collections.deque with popleft()
deque.popleft() is O(1); list.pop(0) is O(n).
What is the average cost of checking key in d for a Python dict with n keys?Related
Answer: O(1)
Hashing jumps almost straight to the right slot, so the average cost does not grow with n.
In JavaScript, what is the usual way to avoid the O(n) cost of shift() in a queue?Related
Answer: Keep a head index that moves forward, or use a linked list
Moving an index is O(1); the used part of the array can be dropped now and then.
From Queues and deques
What is the worst-case lookup time of std::unordered_map?Related
Answer: O(n)
If many keys collide into one bucket, a lookup checks them one by one.
Which line is valid Python?Related
Answer: ["even" if x % 2 == 0 else "odd" for x in nums]
An if-else choice goes before the for. A lone if (a filter) must go after the for.
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “Thinking in Big-O”. The module exam comes next.
- Module 1 exam: Thinking in Big-O · 14 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Arrays and strings. 61 topics left in the course before the final exam.
← Previous: Best, average and worst case; analysing loops and recursion