Week 5: Lists & Collections
2277 words
11 min read
Visual companion
Python
Type and operator map
Python Week 1: the first filter for runtime behavior
View
Revision summary
What this note is really saying
Short form
# Week 5: Lists & Collections > **BSCS1001 — IIT Madras BS Degree** **Prerequisite:** Weeks 1-4 (Iteration, Filtering, Procedures) **Cross-links:** BSCS1002-Python (Week 6 — Lists), BSCS2002-PDSA (Week 2 — Collections) ## 1. Motivation: Beyond Simple Variables So far, we've used **scalar variables** — counters, accu...

Week 5: Lists & Collections
BSCS1001 — IIT Madras BS Degree Prerequisite: Weeks 1-4 (Iteration, Filtering, Procedures) Cross-links: BSCS1002-Python (Week 6 — Lists), BSCS2002-PDSA (Week 2 — Collections)
1. Motivation: Beyond Simple Variables
So far, we've used scalar variables — counters, accumulators, max trackers. These hold single values.
But what if we need to track a collection of items?
| Problem | What We Need | Why a Single Variable Won't Work |
|---|---|---|
| Students born in May | List of their IDs | We need ALL matching IDs, not just count |
| Top 3 marks | List of 3 values | Need to store all 3, not just max |
| Customers who bought food | List of names | Many customers, need all of them |
| Words after an adjective | List of words | Multiple matches, need to collect |
Lists are the solution: a single variable that holds a sequence of values.
Real-world analogy: A variable is like a post-it note (holds one thing). A list is like a notebook (holds many things in order).
2. What is a List?
A list is a sequence of values. A single variable refers to the entire sequence.
List Notation
pseudo// A list of integers [1, 13, 2] // A list of strings ["Vedanayagam", "cane", "Monday", "school"] // An empty list []
Visual Representation
(Diagram)
Actually, lists are not linked like this in our pseudocode — they are conceptually sequences. We access elements by iterating through them, not by index directly.
Key Properties
| Property | Description |
|---|---|
| Ordered | Elements have a defined order |
| Mutable | Can add, remove, change elements |
| Heterogeneous? | Usually same type (but not required) |
| Dynamic | Can grow and shrink |
3. List Operations
Basic List Operations
| Operation | Syntax | Example | Result |
|---|---|---|---|
| Create empty | [] | L = [] | [] |
| Create with values | [v1, v2, ...] | L = [1, 2, 3] | [1, 2, 3] |
| Append (concat) | L1 ++ L2 | [1,2] ++ [3,4] | [1,2,3,4] |
| Extend with item | L = L ++ [x] | L=[1]; L=L++[2] | [1,2] |
| Length | length(L) | length([1,2,3]) | 3 |
| First element | first(L) | first([1,2,3]) | 1 |
| Rest of list | rest(L) | rest([1,2,3]) | [2,3] |
| Last element | last(L) | last([1,2,3]) | 3 |
| All but last | init(L) | init([1,2,3]) | [1,2] |
Important: How ++ Works
pseudoL1 = [1, 13] L2 = [2, 17, 1] L1 ++ L2 = [1, 13, 2, 17, 1] // Concatenation, not addition
Extending a List
pseudo// To add one item x to list L: L = L ++ [x] // Example: Students = ["Alice"] Students = Students ++ ["Bob"] // ["Alice", "Bob"] Students = Students ++ ["Charlie"] // ["Alice", "Bob", "Charlie"]
4. Building Lists with Iteration
Pattern: Collect Matching Items
sqlResultList = [] while (Pile 1 has more cards) { Pick a card X from Pile 1 Move X to Pile 2 if (condition) { ResultList = ResultList ++ [X.Id] } }
Worked Example: Students from Chennai
pseudochennaiList = [] while (Table 1 has more rows) { Read the first row X in Table 1 if (X.TownCity == "Chennai") { chennaiList = chennaiList ++ [X.Seqno] } Move X to Table 2 }
Dataset:
| SeqNo | Name | TownCity |
|---|---|---|
| 1 | Alice | Chennai |
| 2 | Bob | Mumbai |
| 3 | Charlie | Chennai |
| 4 | Diana | Delhi |
Tracing:
| Iter | X.SeqNo | X.TownCity | Condition | chennaiList |
|---|---|---|---|---|
| Start | — | — | — | [] |
| 1 | 1 | Chennai | ✅ Match | [1] |
| 2 | 2 | Mumbai | ❌ No | [1] |
| 3 | 3 | Chennai | ✅ Match | [1, 3] |
| 4 | 4 | Delhi | ❌ No | [1, 3] |
Result:
chennaiList = [1, 3] (students from Chennai)Building Multiple Lists in One Pass
We can build several lists simultaneously:
pseudomayList = [] chennaiList = [] while (Table 1 has more rows) { Read the first row X in Table 1 if (X.BirthMonth == "May") { mayList = mayList ++ [X.Seqno] } if (X.TownCity == "Chennai") { chennaiList = chennaiList ++ [X.Seqno] } Move X to Table 2 }
5. Processing Lists: Foreach
Once we have a list, we often need to process each element.
The Foreach Loop
pseudoforeach x in L { Do something with x }
This iterates through each value in the list L, assigning each to x in turn.
Example: Sum All Elements in a List
pseudoProcedure SumList(L) { total = 0 foreach x in L { total = total + x } return(total) End SumList // Usage: result = SumList([10, 20, 30]) // result = 60
Example: Find Maximum in a List
pseudoProcedure MaxList(L) { max = first(L) // Initialize with first element foreach x in L { if (x > max) { max = x } } return(max) End MaxList
Foreach vs While
| Aspect | foreach | while |
|---|---|---|
| Purpose | Iterate through a collection | General repetition |
| Termination | When all elements processed | When condition becomes false |
| Risk | Can't accidentally infinite loop | Must ensure condition changes |
| Use with | Lists, dictionaries | Datasets (cards), any condition |
6. Lists of Records and Complex Types
List of Pairs (Tuples)
Sometimes each element in a list is itself a pair:
pseudo// List of (student ID, marks) pairs marksList = [(101, 85), (102, 92), (103, 78)]
List of Triples
pseudo// List of (student ID, subject, marks) triples gradeList = [(101, "Maths", 85), (101, "Physics", 78), (102, "Maths", 92)]
Nested Lists (List of Lists)
pseudo// Each student has a list of subject marks marksMatrix = [ [85, 78, 92], // Student 1: Maths, Physics, Chemistry [72, 88, 65], // Student 2 [91, 85, 78] // Student 3 ]
List of Records
sql// List where each element is a record with named fields // Using our marks card record type marksCardList = [ {SeqNo: 1, Name: "Alice", Maths: 85, Physics: 78}, {SeqNo: 2, Name: "Bob", Maths: 72, Physics: 88}, {SeqNo: 3, Name: "Charlie", Maths: 91, Physics: 85} ]
7. The Three Prizes Problem with Lists
This problem from Week 3 now becomes much more natural with lists.
Step 1: Procedure for Third Highest Mark
pseudoProcedure TopThreeMarks(Subj) { max = 0 secondmax = 0 thirdmax = 0 while (Table 1 has more rows) { Read the first row X in Table 1 if (X.Subj > max) { thirdmax = secondmax secondmax = max max = X.Subj } if (max > X.Subj AND X.Subj > secondmax) { thirdmax = secondmax secondmax = X.Subj } if (secondmax > X.Subj AND X.Subj > thirdmax) { thirdmax = X.Subj } Move X to Table 2 } return(thirdmax) End TopThreeMarks
Step 2: Build Lists of Top Students
pseudocutoffMaths = TopThreeMarks(Mathematics) cutoffPhys = TopThreeMarks(Physics) cutoffChem = TopThreeMarks(Chemistry) mathsList = [] physList = [] chemList = [] while (Table 1 has more rows) { Read the first row X in Table 1 if (X.Mathematics >= cutoffMaths) { mathsList = mathsList ++ [X.SeqNo] } if (X.Physics >= cutoffPhys) { physList = physList ++ [X.SeqNo] } if (X.Chemistry >= cutoffChem) { chemList = chemList ++ [X.SeqNo] } Move X to Table 2 }
Step 3: Find Common Elements Across Lists
pseudo// Students in both Maths AND Physics top-3 mathsPhysList = [] foreach x in mathsList { foreach y in physList { if (x == y) { mathsPhysList = mathsPhysList ++ [x] } } } // Then match with Chemistry mathsPhysChemList = [] foreach x in mathsPhysList { foreach y in chemList { if (x == y) { mathsPhysChemList = mathsPhysChemList ++ [x] } } }
8. Nested Foreach with Lists
Finding Common Elements in Two Lists
pseudoProcedure FindCommon(L1, L2) { common = [] foreach x in L1 { foreach y in L2 { if (x == y) { common = common ++ [x] } } } return(common) End FindCommon
Tracing: Find Common
L1 = [1, 3, 5, 7], L2 = [3, 7, 9]
| Outer x | Inner y | Match? | common |
|---|---|---|---|
| 1 | 3 | ❌ | [] |
| 1 | 7 | ❌ | [] |
| 1 | 9 | ❌ | [] |
| 3 | 3 | ✅ | [3] |
| 3 | 7 | ❌ | [3] |
| 3 | 9 | ❌ | [3] |
| 5 | 3 | ❌ | [3] |
| 5 | 7 | ❌ | [3] |
| 5 | 9 | ❌ | [3] |
| 7 | 3 | ❌ | [3] |
| 7 | 7 | ✅ | [3, 7] |
| 7 | 9 | ❌ | [3, 7] |
Result:
common = [3, 7]Complexity: Nested Foreach
This is exactly the nested iteration from Week 4:
If both lists have roughly N/2 items, that's O(N²/4) comparisons.
9. Comparison: Lists vs Variables
Scalar Variables vs Lists
| Aspect | Scalar Variable | List |
|---|---|---|
| Holds | Single value | Multiple values |
| Memory | One value at a time | Sequence of values |
| Update | x = newValue | L = L ++ [newValue] |
| Iteration | Not applicable | foreach x in L |
| Use case | Count, sum, max, min | Collection of matches |
When to Use a List
(Diagram)
10. Practice Questions
Basic Questions
Q1. What is a list? Give an example.
Show AnswerA list is a sequence of values. Example:[1, 13, 2]or["Alice", "Bob", "Charlie"]. Q2. What is the result of[1, 2, 3] ++ [4, 5]? Show Answer[1, 2, 3, 4, 5]— the++operator concatenates two lists. Q3. Write pseudocode to build a list of all students who scored above 90 in Maths. Show AnswersqltopMaths = [] while (Pile 1 has more cards) { Pick a card X from Pile 1 Move X to Pile 2 if (X.Maths > 90) { topMaths = topMaths ++ [X.Id] } }
Q4. What does
foreach x in L do?Show AnswerIt iterates through each element of list L, assigning each element in turn to variablex. The code inside the loop executes once for each element.
Intermediate Questions
Q5. Trace this pseudocode:
pseudoL = [] L = L ++ [5] L = L ++ [3] L = L ++ [8] L = L ++ [3]
What is L at the end?
Show Answer
| Step | L after |
|---|---|
L = [] | [] |
L = [] ++ [5] | [5] |
L = [5] ++ [3] | [5, 3] |
L = [5, 3] ++ [8] | [5, 3, 8] |
L = [5, 3, 8] ++ [3] | [5, 3, 8, 3] |
Final:[5, 3, 8, 3]Q6. Write a procedure that takes a list of numbers and returns a new list with only the even numbers. Show AnswerpseudoProcedure FilterEven(L) { result = [] foreach x in L { if (x % 2 == 0) { result = result ++ [x] } } return(result) End FilterEven // Example: FilterEven([1, 2, 3, 4, 5]) → [2, 4]
Q7. Explain the difference between
first(L) and last(L).Show Answer
first(L)returns the first element of list L (the one at the beginning).last(L)returns the last element of list L (the one at the end).- For L = [10, 20, 30]:
first(L) = 10,last(L) = 30Q8. Write pseudocode using foreach to find the sum of all numbers in a list. Show AnswerpseudoProcedure SumList(L) { total = 0 foreach x in L { total = total + x } return(total) End SumList
Advanced Questions
Q9. Write pseudocode to find common elements across THREE lists (L1, L2, L3).
Show AnswerpseudoProcedure FindCommon3(L1, L2, L3) { // First find common in L1 and L2 common12 = [] foreach x in L1 { foreach y in L2 { if (x == y) { common12 = common12 ++ [x] } } } // Then find common between common12 and L3 common123 = [] foreach x in common12 { foreach y in L3 { if (x == y) { common123 = common123 ++ [x] } } } return(common123) End FindCommon3
Q10. What is the time complexity of finding common elements in two lists using nested foreach? How could you improve it?
Show AnswerThe nested foreach approach has O(N×M) complexity where N and M are lengths of the lists. If both have ~N elements, this is O(N²).Improvements:
- Sort both lists first then use a linear merge (O(N log N))
- Use a dictionary to store elements of one list (O(N+M)) — covered in Week 6
- If one list is small, put the small list in the outer loop Q11. Design an algorithm using lists to find all students who scored above average in Maths AND are also in the top 3 of Physics. Show Answer
pseudo// Step 1: Compute average Maths Sum = 0, Count = 0 while (Pile 1 has more cards) { Pick X; Sum += X.Maths; Count += 1; Move X } AvgMaths = Sum / Count // Step 2: Build list of above-average Maths students aboveAvgMaths = [] // Need to re-scan... but cards are in Pile 2 now while (Pile 2 has more cards) { Pick X if (X.Maths > AvgMaths) { aboveAvgMaths = aboveAvgMaths ++ [X.Id] } Move X to Pile 1 } // Step 3: Get top 3 Physics cutoff thirdPhys = TopThreeMarks(Physics) // Step 4: Build list of top 3 Physics students topPhys = [] while (Pile 1 has more cards) { Pick X if (X.Physics >= thirdPhys) { topPhys = topPhys ++ [X.Id] } Move X } // Step 5: Find common result = FindCommon(aboveAvgMaths, topPhys)
Q12. Compare the
while loop and foreach loop. When would you use each?Show Answer
| Aspect | while | foreach |
|---|---|---|
| When to use | Dataset iteration, general repetition | Iterating through a list |
| Termination condition | Explicit condition | End of collection |
| Infinite loop risk | Yes (if condition never false) | No (fixed number of elements) |
| Control | More flexible | Simpler, safer |
| Example | while (Pile 1 has more cards) | foreach x in myList |
Guideline: Useforeachwhen processing a list you've already built. Usewhilewhen reading from a dataset.
📚 Cross-References
| Course | Topic | Connection |
|---|---|---|
| BSCS1002 (Python) | Week 6 — Lists | Python list operations, for x in L |
| BSCS2002 (PDSA) | Week 2 — Arrays vs Lists | List as ADT |
| BSCS2002 (PDSA) | Week 5 — Sorting | Sorting lists |
Next Topic: 10 — Insertion SortQuiz Tip: List-building and foreach questions are common in Quiz 2. Practice tracing list state! Join Discord PreviousBinning & Complexity IntroductionNextInsertion Sort