Home / Computer Science / Class XI / Lists
Lists — CUET Computer Science hero
Class XI 💻 Computer Science Ch 9 of 19

Lists

CUET unit: Lists (Python Data Structures)

📌 Snapshot

  • Master Python lists for CUET: indexing, slicing, methods, copying and what happens inside functions.
  • Why a list can be changed in place, and how that causes aliasing, in place sorting and shared nested lists.
  • Tables for append versus extend, remove versus pop, sort versus sorted, and every copying method.
  • Output tracing practice that targets the favourite traps: methods returning None and one list with two names.

📖 Detailed Notes

Written and reviewed by Rohit Singh, Computer Science & Commerce faculty at UniDrill (MCA, Osmania University · 6 years teaching). Based on NCERT Computer Science Class XI, Chapter 9.

One list, two names, two surprises

Imagine you make a shopping list on paper and your friend says "give me a copy". If you hand over the same sheet and then add milk, your friend's list has milk too. If you photocopy it first, adding milk changes only yours. Python lists behave exactly like this. Writing list2 = list1 hands over the same sheet, not a photocopy. Most of the hard CUET questions on this chapter come from this one fact, together with a second one: some list methods change the list and return nothing, which makes print(list1.sort()) display None.

What is a list?

A list is an ordered sequence of one or more elements, enclosed in square brackets and separated by commas. Unlike a string, which holds only characters, a list can mix integers, floats, strings, tuples and even other lists. Most importantly, a list is mutable: its contents can be changed after it is created.

Code
list1 = [2, 4, 6, 8, 10, 12]
list2 = ['a', 'e', 'i', 'o', 'u']
list3 = [100, 23.5, 'Hello']
list4 = [['Physics', 101], ['Chemistry', 202], ['Maths', 303]]

The first is a list of even numbers, the second of vowels, the third of mixed types, and the fourth is a nested list: a list whose elements are themselves lists.

Indexing and mutability

Elements are accessed exactly like characters of a string. Indices start at 0 and run to $n - 1$ going forwards, or from $-1$ down to $-n$ going backwards. list1[15] raises IndexError: list index out of range. The index can be an expression that evaluates to an integer, such as list1[1 + 4].

Because lists are mutable, you can assign to a position.

Code
list1 = ['Red', 'Green', 'Blue', 'Orange']
list1[3] = 'Black'
print(list1)
Output
['Red', 'Green', 'Blue', 'Black']

Here is how a list and a string differ in the one place that matters most.

Feature String List
Brackets Quotes Square brackets
Elements Characters only Any data types, even lists
Mutable? No: s[1] = 'a' is a TypeError Yes: list1[3] = 'Black' works
Indexing and slicing Same rules Same rules
Slice gives A string A list

List operations

Operation Symbol Example Result
Concatenation + [1, 3, 5] + [2, 4] [1, 3, 5, 2, 4]
Repetition * ['Hello'] * 4 ['Hello', 'Hello', 'Hello', 'Hello']
Membership in, not in 'Green' in ['Red', 'Green'] True
Slicing [n:m:k] list1[2:6] the elements at indices 2, 3, 4, 5

Concatenation and repetition build a new list and leave the originals unchanged. To keep the result you must assign it. Concatenation needs a list on both sides: [1, 2, 3] + "abc" raises a TypeError. Membership tests for a whole element, so 'Gre' in ['Red', 'Green'] is False.

Slicing follows the rules you saw for strings: start included, stop excluded, an out of range stop is trimmed, and a start beyond the stop gives an empty list.

Worked example: slicing a list. Let list1 = ['Red','Green','Blue','Cyan','Magenta','Yellow','Black'] (indices 0 to 6).

Expression Indices Result
list1[2:6] 2, 3, 4, 5 ['Blue', 'Cyan', 'Magenta', 'Yellow']
list1[2:20] 2 to the end ['Blue', 'Cyan', 'Magenta', 'Yellow', 'Black']
list1[7:2] none []
list1[:5] 0 to 4 ['Red', 'Green', 'Blue', 'Cyan', 'Magenta']
list1[0:6:2] 0, 2, 4 ['Red', 'Blue', 'Magenta']
list1[-6:-2] 1, 2, 3, 4 ['Green', 'Blue', 'Cyan', 'Magenta']
list1[::2] 0, 2, 4, 6 ['Red', 'Blue', 'Magenta', 'Black']
list1[::-1] 6 down to 0 the whole list in reverse order

Traversing a list

You can visit every element in three ways.

Style Code Best when
for over the elements for item in list1: You need the values only
for over the indices for i in range(len(list1)): then list1[i] You need the position as well, or you want to change elements
while loop i = 0, then while i < len(list1): and i += 1 The stopping rule is more complex

To change elements while looping, use the index form. Assigning to the loop variable in for item in list1 only changes item, not the list.

List methods and built in functions

A method is called with a dot, such as list1.append(50). The big question for each method is: does it change the list in place, or return a new value?

Adding elements

Method What it does Example Result
append(x) Adds one element at the end; a list stays one element [10,20,30,40].append([50,60]) [10, 20, 30, 40, [50, 60]]
extend(seq) Adds each element of a list at the end [10,20,30].extend([40,50]) [10, 20, 30, 40, 50]
insert(i, x) Puts x at index i, shifting the rest right [10,20,30,40,50].insert(2, 25) [10, 20, 25, 30, 40, 50]

Removing elements

Method What it does Example Result
remove(x) Deletes the first occurrence of the value; ValueError if absent [10,20,30,40,50,30].remove(30) [10, 20, 40, 50, 30]
pop(i) Deletes the element at index i and returns it [10,20,30,40,50,60].pop(3) returns 40; list is [10, 20, 30, 50, 60]
pop() With no index, removes and returns the last element [10,20,30,40,50,60].pop() returns 60
del list1[i] Deletes by index (a statement, not a method); also works with a slice del myList[3:] on 1 to 10 [1, 2, 3]

Searching and counting

Method What it returns Example Result
count(x) How many times x appears [10,20,30,10,40,10].count(10) 3
index(x) Index of the first occurrence; ValueError if absent [10,20,30,20,40,10].index(20) 1

Ordering

Method What it does Returns Changes the list?
reverse() Reverses the order None Yes, in place
sort() Sorts ascending; sort(reverse=True) sorts descending None Yes, in place
sorted(list1) Builds a new sorted list The new list No

Measuring and converting

Function What it returns Example Result
len(list1) Number of elements len([10,20,30,40,50]) 5
min(), max(), sum() Smallest, largest, total sum([34,12,63,39,92,44]) 284
list() An empty list list() []
list(seq) A list made from any sequence list('aeiou') ['a', 'e', 'i', 'o', 'u']

Worked example: append or extend? Start with list1 = [10, 20, 30] each time.

Statement Result Length
list1.append([40, 50]) [10, 20, 30, [40, 50]] 4
list1.extend([40, 50]) [10, 20, 30, 40, 50] 5

Append adds its argument as a single element, so a list argument becomes a nested list. Extend unpacks its argument and adds the items one by one.

Worked example: tracing a sequence of changes. Start with L = [10, 20, 30, 40].

Statement Effect L afterwards Value returned
L.append(50) Adds 50 at the end [10, 20, 30, 40, 50] None
L.insert(2, 25) 25 goes to index 2 [10, 20, 25, 30, 40, 50] None
L.remove(30) Deletes the value 30 [10, 20, 25, 40, 50] None
L.pop() Removes the last element [10, 20, 25, 40] 50
L.pop(1) Removes index 1 [10, 25, 40] 20

A common mistake is to confuse remove and pop: remove(30) looks for the value 30, but pop(3) removes the item at index 3.

Pause and predict: L = [3, 1, 2]. What do print(L.sort()) and then print(L) show? What if the first line were print(sorted(L))?

Check your answer: L.sort() sorts the list in place and returns None, so the first print shows None and the second shows [1, 2, 3]. With sorted(L) the first print shows the new sorted list [1, 2, 3], while L itself would still be [3, 1, 2].

Beyond the textbook. For the exam: sort() changes the list and sorted() returns a new one. In reality: the reason sort() returns None is a deliberate design choice, so that nobody mistakes an in place change for a copy. The pattern is general: in Python, methods that modify a mutable object in place return None. Whenever you see x = x.sort(), suspect a bug, because x becomes None.

Nested lists

When a list is an element of another list, you need two indices to reach inside it. list1[i][j] first picks the element i (the inner list) and then element j of that.

Worked example: reading a nested list. Let stRecord = ['Raman', 'A-36', [56, 98, 99, 72, 69], 78.8].

What you want Expression Result
Percentage stRecord[3] 78.8
Roll number stRecord[1] 'A-36'
Marks in the fifth subject stRecord[2][4] 69
Highest marks max(stRecord[2]) 99
Change the name stRecord[0] = 'Raghav' the list is updated in place

Copying lists: aliasing

The statement list2 = list1 does not create a new list. It makes list2 a second name (an alias) for the same list object. A change through either name is visible through both.

Worked example: the alias trap.

Code
list1 = [1, 2, 3]
list2 = list1
list1.append(10)
print(list2)
Step What happens Memory picture
1 list1 = [1, 2, 3] list1 refers to one list object
2 list2 = list1 list2 refers to the same object; no new list
3 list1.append(10) The shared object becomes [1, 2, 3, 10]
4 print(list2) [1, 2, 3, 10]

To get a real, independent copy there are three methods.

Method Code Result
Slicing newList = oldList[:] A new, distinct list
The list() function newList = list(oldList) A new, distinct list
The copy module import copy, then newList = copy.copy(oldList) A new, distinct list

After a real copy, list1.append(10) changes only list1.

Beyond the textbook. For the exam: slicing, list() and copy.copy() each make an independent copy. In reality: all three make a shallow copy. The outer list is new, but any inner lists are still shared. With a = [1, [2, 3]] and b = copy.copy(a), running b[1].append(9) changes the inner list seen through both a and b. When you need every level duplicated, use copy.deepcopy(a).

Beyond the textbook. For the exam: + creates a new list. In reality: the shorthand += behaves differently on lists: it extends the existing list in place. After a = [1, 2, 3] and b = a, the statement a = a + [4] leaves b as [1, 2, 3], because a now refers to a new list. But a += [4] changes the shared list, and b becomes [1, 2, 3, 4] too. This is why the textbook asks you to distinguish list1 * 2, list1 *= 2 and list1 = list1 * 2: the first creates a list that is thrown away, the second changes list1 itself, and the third rebinds list1 to a new list.

A list as an argument to a function

When you pass a list to a function, you pass a reference to the same list object. This leads to two cases, and the difference is a very popular question.

Case What the function does Effect on the caller's list
Changes the list in place (L[i] += 5, L.append(1)) Works on the shared object Changed: the caller sees it
Assigns a new list to the parameter (L = [15, 25], or L = L + [1]) The parameter now points to a new local list Unchanged

Worked example: in place change.

Code
def increment(list2):
    for i in range(0, len(list2)):
        list2[i] += 5
list1 = [10, 20, 30, 40, 50]
increment(list1)
print(list1)
Output
[15, 25, 35, 45, 55]

list2 and list1 have the same id(), so each list2[i] += 5 edits the caller's list.

Worked example: reassignment.

Code
def increment(list2):
    list2 = [15, 25, 35, 45, 55]
list1 = [10, 20, 30, 40, 50]
increment(list1)
print(list1)
Output
[10, 20, 30, 40, 50]

The assignment makes list2 refer to a brand new list, so its id() changes and the connection to list1 is cut. The caller's list is untouched.

Pause and predict: a function contains L = L + [1] and is called with x = [5]. What is x afterwards? What if the line were L.append(1)?

Check your answer: with L = L + [1], a new list is created and stored in the local name, so x is still [5]. With L.append(1), the shared list is changed in place, so x becomes [5, 1].

Two classic list programs

Worked example: linear search. The function checks the elements one by one and returns the index where the number is found, or None if it never is.

Code
def linearSearch(num, list1):
    for i in range(0, len(list1)):
        if list1[i] == num:
            return i
    return None
print(linearSearch(12, [23, 567, 12, 89, 324]))
Pass i list1[i] Equal to 12?
1 0 23 No
2 1 567 No
3 2 12 Yes, return 2 ends the function

The function returns index 2, which a user would report as position 3 (the program prints result + 1). return None is reached only if the loop finishes without a match.

Worked example: average marks. To average the marks of 5 students, the program starts with an empty list, uses append() inside a loop to collect each mark, then sums them in a function and divides by n. For the marks 45, 89, 79, 76, 55 the total is 344, and $344 / 5 = 68.8$.

Exam traps

The trap Why it's tempting The truth
list2 = list1 makes a copy The values look the same It creates an alias; use list1[:] or list(list1) for a copy
print(L.sort()) prints the sorted list Sorting sounds like it gives output sort() returns None and sorts in place
sorted(L) sorts L It sounds like sort It returns a new list; L is unchanged unless you assign
append([4, 5]) adds two elements The list holds two items It adds one element, a nested list; extend adds two
remove(3) deletes the element at index 3 pop(3) and del L[3] do remove deletes by value (the first 3 it finds); pop and del delete by index
[1, 2] + 'ab' works Concatenation is general Both sides must be lists, otherwise TypeError
L = L + [1] inside a function changes the caller's list Lists are mutable It rebinds the local name; only in place changes show up
Slicing a list raises IndexError A single bad index does Slices are trimmed; [1, 2][5:] is []

60-second revision

Topic Lock this in
List Ordered, mutable, mixed types, square brackets; indexing as in strings
+ / * Need lists on both sides / repeat a list; both make a new list
in Tests for an element, not a part of an element
Add append (one item), extend (each item), insert(i, x)
Remove remove(value), pop(index) returns the item, pop() takes the last, del L[i] or del L[a:b]
Find count(x), index(x) (ValueError if absent)
Order sort() and reverse() return None; sorted() returns a new list
Totals len, min, max, sum
Nested L[i][j]
Copy = is an alias; [:], list(), copy.copy() are shallow copies
In a function In place changes are seen by the caller; reassigning the parameter is not
Linear search Compare one by one, return the index or None

Where this chapter connects

  • Previous: Strings introduced indexing, slicing, concatenation and membership, all of which work the same way on lists.
  • Next: Tuples and Dictionaries compares the mutable list with the immutable tuple, and adds the key based dictionary.
  • Also related: Functions explains parameters and return values, and Working with Lists and Dictionaries in the Informatics Practices course extends the same ideas.

🎯 Practice MCQs

First 3 questions free · create a free account to unlock the rest — answers & explanations included, no payment needed

Q1. If L = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], what is L[::-2]?

▸ Show answer & explanation

Answer: A

A negative step starts from the last element and moves left two places at a time: 10, 8, 6, 4, 2. Option B would start from the second last element, and option D goes left to right.

Q2. Consider: (1) list1 = [10, 20, 30] (2) list1.append([40, 50]) (3) print(len(list1)). What is printed?

▸ Show answer & explanation

Answer: B

The append method adds its argument as one single element, so the list becomes [10, 20, 30, [40, 50]], which has 4 elements. Option C would be the result of extend.

Q3. Assertion (A): print(L.sort()) displays None. Reason (R): The sort method arranges the elements of the list in place and returns nothing.

▸ Show answer & explanation

Answer: A

The sort method changes the original list and returns None. Printing its return value therefore shows None, so R explains A.

🔒 12 more practice MCQs

Create a free account to unlock every MCQ in this chapter — answers and explanations included. No payment needed.

Already registered? Just log in and they'll all appear here.

📊 Previous-Year Questions

Practise with real CUET Computer Science previous-year papers — every question solved, with the correct answer and a step-by-step explanation.

View solved CUET PYQ papers →

Ready to drill Computer Science?

Unlock all MCQs, chapter tests, mocks & PYQs for ₹199/year.

Get UniDrill Pro