LambdaLabTM
Computer Science · Class 11 · Lists Revisited
ProgramsBuilt-ins⏱️ 16 min read

The Built-in Way

Three pages of loops, and Python could have answered most of them in one line. That is not a joke at your expense — the loops are what the exam is testing, and they are what you need the moment the rule gets fussy. But a programmer who only knows the loop writes twelve lines where one would do, so this page is the other half: the same problems, solved with what is already there.

1Program 1 — four questions, five lines

📋 The problem

Total, average, largest, smallest and how many — for a list of marks.

builtins.py
# everything the first programming page did, in five lines

marks = [72, 65, 88, 91, 54]

print('Total:  ', sum(marks))
print('Average:', sum(marks) / len(marks))
print('Largest:', max(marks))
print('Smallest:', min(marks))
print('How many:', len(marks))
Output
Total:   370
Average: 74.0
Largest: 91
Smallest: 54
How many: 5
Watch Out
There is no average() in Python. Writing average(marks) gives NameError: name 'average' is not defined. The average is sum(marks) / len(marks) — two built-ins and a division — and that is the whole of it. It catches people out because sum, max, min and len all exist, so a fifth one feels like it ought to.
The same answers, both ways
the questionthe loopthe built-in
add them upa total, 3 linessum(marks)
the averagea total, then a dividesum(marks) / len(marks)
the largesta champion, 3 linesmax(marks)
where is it?an index loop with a breakmarks.index(max(marks))
how many 4s?a counter, 3 linesnumbers.count(4)
is 4 there?a loop with for…else4 in numbers
put it in ordera sorting algorithmmarks.sort()
how many different?a not-in looplen(set(numbers))

2Program 2 — where is the largest mark?

📋 The problem

Print the highest mark and the position it sits at.

where_largest.py
# where is the largest mark?

marks = [72, 65, 88, 91, 54]

best = max(marks)
where = marks.index(best)

print('The highest mark is', best)
print('It is at position', where)
Output
The highest mark is 91
It is at position 3
Key Takeaway
max() gives the value; index() turns a value into a position. The two together are the built-in answer to “which is biggest and where”. Note index() finds the first occurrence: if 91 appeared twice, this reports the earlier one and says nothing about the other.
Watch Out
index() raises when the value is not there. marks.index(50) gives ValueError: 50 is not in list — it does not answer −1 the way a string's find() does. Ask if 50 in marks: first, or use the for…else search that reports the miss itself.

3Program 3 — the second largest, by removing the largest

The counting page spent a page and a half on this, because the loop version is genuinely fiddly. Here is the idea that makes it easy: find the largest, take it out, and ask for the largest again.

second_builtin.py
# the second largest, by removing the largest and asking again

numbers = [45, 88, 12, 91, 67]
working = list(numbers)

largest = max(working)
working.remove(largest)
second = max(working)

print('The list:      ', numbers)
print('After removing', largest, ':', working)
print('Largest:       ', largest)
print('Second largest:', second)
print('Second largest is at position', numbers.index(second), 'of the original')
Output
The list:       [45, 88, 12, 91, 67]
After removing 91 : [45, 88, 12, 67]
Largest:        91
Second largest: 88
Second largest is at position 1 of the original
working = list(numbers)

A COPY. list() builds a new list holding the same items, so everything that follows happens to the copy. Without this line the original loses its largest value permanently — remove() changes the list it is called on.

working.remove(largest)

remove() takes a VALUE, not a position, and deletes the first item equal to it. That is exactly what is wanted here: the largest value, gone.

second = max(working)

The largest of what is left is the second largest of what there was. One line, and no champions to initialise.

numbers.index(second)

Asked of the ORIGINAL list, because the position in the copy would be wrong for anything after the removed item. Position 1 in the original; it would also be 1 here, but on a list where the largest came first it would not be.

Watch Out
Without the copy, numbers is changed for good. numbers.remove(max(numbers)) leaves [45, 88, 12, 67] in the original, so anything later in the program that expects all five values is now quietly wrong. If the question does not mind, drop the copy; if it prints the list afterwards, the copy is the difference between right and wrong.

It answers a slightly different question, and you must know which. On a list where the largest value appears twice, removing one of them leaves the other — so the second largest comes out equal to the largest:

second_builtin.py — with numbers = [91, 91, 45]
Output
The list:       [91, 91, 45]
After removing 91 : [91, 45]
Largest:        91
Second largest: 91
Second largest is at position 0 of the original

That is the second largest item, which is what sorted(numbers)[-2] also gives. The loop version on the counting page answers 45 — the second largest value. Both are defensible; read the question, and if it is ambiguous, say in a comment which one you have written.

Watch Out
A one-item list breaks it. Remove the only item and max() is asked about an empty list: ValueError: max() iterable argument is empty. A guard — if len(numbers) < 2: — is the honest fix, and it is the same empty-list thinking as the page before this one.
second_builtin.py

4Program 4 — remove the duplicates with set()

The changing page removed repeats with a loop and a not in test. There is a type whose whole purpose is that it cannot hold the same value twice, and handing a list to it does the work:

dedupe_set.py
# the repeats removed, with a set

numbers = [4, 7, 4, 2, 7, 9, 4]

different = set(numbers)
as_a_list = sorted(different)

print('Original:     ', numbers)
print('How many different values:', len(different))
print('Sorted, no repeats:', as_a_list)
Output
Original:      [4, 7, 4, 2, 7, 9, 4]
How many different values: 4
Sorted, no repeats: [2, 4, 7, 9]
different = set(numbers)

set() builds a set from the list, and a set simply refuses a value it already holds. The duplicates are not deleted one by one — there was never anywhere to put them.

len(different)

How many DIFFERENT values there were. One built-in call answers a question that took a loop and a growing list before.

sorted(different)

Back to a list, in order. sorted() takes a set perfectly happily and always hands back a list.

Watch Out
A set has no order, so the original order is lost. list(set([4, 7, 4, 2, 7, 9, 4])) gives [9, 2, 4, 7] — not the order they were typed in, and not sorted either. That is why the program above says sorted() and not list(): sorting is a decision, and it is the only way to get a predictable answer out of a set. If the original order matters, the loop version is the one you want.
Note
Sets are not in the CBSE Class 11 syllabus — they are covered on this site as a bonus at the end of Data Types. Use set() when you are writing your own code, and know the not in loop for the paper, which is what “without using a set” is asking for.

5Program 5 — sort() against sorted()

📋 The problem

Put a list in order — twice, once each way — and see what happens to the original.

sorting.py
# the two ways of putting a list in order

marks = [45, 88, 12, 91, 67]

in_order = sorted(marks)

print('sorted() gave', in_order)
print('marks is still', marks)

marks.sort()

print('after marks.sort(), marks is', marks)
print('and sort() itself returned', [45, 88].sort())
print('descending:', sorted([45, 88, 12], reverse=True))
Output
sorted() gave [12, 45, 67, 88, 91]
marks is still [45, 88, 12, 91, 67]
after marks.sort(), marks is [12, 45, 67, 88, 91]
and sort() itself returned None
descending: [88, 45, 12]
Key Takeaway
sorted() answers; sort() changes. sorted(marks) hands back a new list and leaves the original alone. marks.sort() rearranges the original and hands back None — which is why marks = marks.sort() is the mistake that throws the list away, exactly like marks = marks.append(x).

With sorting available, three of the earlier programs become one line each: the largest is sorted(marks)[-1], the smallest is sorted(marks)[0], and the middle value of an odd-length list is sorted(marks)[len(marks) // 2].

6So which do you write?

Write the loop when the question says so

'Without using max()', 'using a loop', 'write an algorithm to…' — all of them mean the long version, and a one-line answer scores nothing however right it is.

Write the loop when no built-in fits

Count the evens above the average. Find the first value that repeats. Split into two lists. There is no function for any of those.

Use the built-in in your own programs

sum(marks) cannot have an off-by-one, cannot start its collector at the wrong value, and says what it means at a glance.

Know both, and know what each really answers

Second largest item or second largest value? Order kept or order lost? The two versions differ, and the difference is where the marks are.

Key Takeaway
Every built-in here is a loop somebody else wrote. max() walks the list keeping a champion, exactly as your program did; sum() keeps a total; in is a linear search that stops when it finds something. Nothing on this page is magic — it is the same three pages of loops, packaged. That is worth knowing, because it is also why they fail on an empty list in the same way yours does.

7Recap

sum, len, max, min — and no average()

The average is sum(marks) / len(marks). average() does not exist and gives a NameError.

max() then remove() then max() again

The second largest in three lines. Copy the list first with list(numbers), or the original loses its largest value for good.

set() removes duplicates and the order

len(set(numbers)) is how many different values. sorted(set(numbers)) to get a predictable list back — never list(set(...)).

sorted() answers, sort() changes

sort() returns None, so marks = marks.sort() destroys the list. Both take reverse=True for descending order.

✍️ Now write these yourself
  1. 1

    Find the third largest value by removing the largest twice.

    Hint · The same three lines, one more time — and think about what a list of two items would do.

  2. 2

    Print the range of a list: the largest minus the smallest.

    Hint · max(marks) - min(marks). One line, and worth writing the loop version once to compare.

  3. 3

    Report how many values appear more than once, using count().

    Hint · Loop over set(numbers) and test numbers.count(v) > 1.

  4. 4

    Print the top three marks, in order, without changing the original list.

    Hint · sorted(marks, reverse=True) and then a slice of the first three.

  5. 5

    Take a list from the user with eval() and print it with the duplicates removed, in the order they were typed.

    Hint · This is the one set() cannot do — the loop with not in is the answer, and that is the point of the exercise.

Quick Check

What does average(marks) do in Python?

Quick Check

numbers.remove(max(numbers)) is used to find the second largest. What is the catch?

Quick Check

list(set([4, 7, 4, 2, 7, 9, 4])) gives [9, 2, 4, 7]. Why not [4, 7, 2, 9]?