On this page23 sections
- Prerequisites
- Connection With Previous Lectures
- Learning Objectives
- 1. What Is an Index?
- 2. Reading an Element
- 3. The Last Index Is length - 1
- 4. first and last
- 5. Replacing an Element
- 6. Replacements Are Type-Checked
- 7. RangeError: an Index That Doesn't Exist
- 8. Visiting Every Index with a for Loop
- 9. Finding a Position with indexOf
- 10. Nullable Elements vs a Nullable List
- 11. A Real-World Example
- Code Examples
- Common Beginner Mistakes
- Best Practices
- Mini Challenge
- Practice Questions
- Practice Answers
- Quick Revision
- Key Takeaways
- What's Next?
Lecture 40 — List Elements & Indexes
| Category | 7 — Lists |
| Lecture | 040 of 140 |
| Estimated video length | 9 min |
| Target | Dart 3.12.2 |
| Level | Beginner |
A
for-inloop hands you every value, but never "just the second one". Indexes let you reach any single element of a list directly — to read it, or to replace it.
Contents
Prerequisites · Connection · Objectives · Lesson · Code Examples · Common Mistakes · Best Practices · Mini Challenge · Practice Questions · Answers · Takeaways
Every error message in this lecture is real. Each one was produced by running the code shown on Dart 3.12.2, so you will recognize it when you meet it yourself.
Prerequisites
Students should already understand, from Lectures 001–039:
- string indexes and
length(Lecture 008) - nullable types and
??(Lectures 013–014) - the counting
forloop and thefor-inloop (Lectures 026–027) - creating a
List<T>,length, andisEmpty(Lecture 039)
Connection With Previous Lectures
In Lecture 039, we created lists and walked through them:
void main() {
var marks = [85, 92, 78];
for (final mark in marks) {
print(mark);
}
}85
92
78Now suppose we want only Sara's mark, the second one. Or the teacher rechecks a paper and the
78 should be 80. A for-in loop cannot do either: it visits every value and its loop
variable is a copy. We need a way to point at one position in the list.
Learning Objectives
By the end of this lecture you will be able to:
- Explain zero-based indexing
- Read any element with
list[index] - Use
first,last, andlength - 1 - Replace an element by assigning to
list[index] - Recognize and avoid a
RangeError - Visit every index with a counting
forloop - Find a value's position with
indexOf - Tell
List<int?>apart fromList<int>?
1. What Is an Index?
Every element in a list sits at a numbered position called its index. Counting starts at 0, exactly as with the characters of a string in Lecture 008.
Analogy — think of a row of lockers at school. Each locker has a number painted on it. To open one, you don't walk past all the others — you go straight to its number.
| Index | 0 | 1 | 2 |
|---|---|---|---|
| Element | 85 | 92 | 78 |
2. Reading an Element
Write the index in square brackets after the list's name:
void main() {
var marks = [85, 92, 78];
print(marks[0]);
print(marks[1]);
print(marks[2]);
}85
92
78marks[1] is the second element, because the first one is at index 0. The index can
be any int expression, such as a variable or i + 1.
3. The Last Index Is length - 1
A list of 3 elements has indexes 0, 1, and 2. The last index is always one less than
the length:
void main() {
var names = ['Ali', 'Sara', 'Zayan'];
print(names.length);
print(names[names.length - 1]);
}3
Zayannames.length - 1 keeps working when the list grows or shrinks; a fixed names[2] does not.
4. first and last
Reading the ends of a list is so common that every list has two shortcuts:
void main() {
var temperatures = [21.5, 25.0, 19.0];
print(temperatures.first);
print(temperatures.last);
}21.5
19.0first is the same as [0], and last the same as [length - 1] — just easier to read.
5. Replacing an Element
Put list[index] on the left of = to store a new value at that position:
void main() {
var marks = [85, 92, 78];
marks[2] = 80;
print(marks);
}[85, 92, 80]The list keeps its length; only the value at index 2 changes. Unlike a string (Lecture
008), a list can be changed in place. Compound operators work too: marks[0] += 5;
adds 5 to the first mark.
6. Replacements Are Type-Checked
A List<int> holds only int values, so the new value must be an int:
void main() {
var marks = [85, 92, 78];
marks[0] = 90.5;
print(marks);
}Error: A value of type 'double' can't be assigned to a variable of type 'int'.
marks[0] = 90.5;
^Each position behaves like a variable of the list's element type.
7. RangeError: an Index That Doesn't Exist
Ask for a position the list doesn't have, and the program compiles — then crashes when it runs:
void main() {
var marks = [85, 92, 78];
print(marks[3]);
}Unhandled exception:
RangeError (length): Invalid value: Not in inclusive range 0..2: 3Read it piece by piece: the valid indexes are 0..2, and we asked for 3. Negative indexes
fail the same way — marks[-1] reports Not in inclusive range 0..2: -1. Dart has no
"count from the end" index; use last instead. Assigning to a missing position, such as
marks[3] = 60;, also throws a RangeError: []= replaces, it never adds. Adding new
elements is the topic of Lecture 041.
8. Visiting Every Index with a for Loop
When you need the position as well as the value, use the counting loop from Lecture 026
with i < list.length:
void main() {
var names = ['Ali', 'Sara', 'Zayan'];
for (var i = 0; i < names.length; i++) {
print('${i + 1}. ${names[i]}');
}
}1. Ali
2. Sara
3. ZayanPeople count from 1, so we print i + 1 but read names[i]. A counting loop can also
change elements, which a for-in loop cannot:
void main() {
var prices = [100, 250, 400];
for (var i = 0; i < prices.length; i++) {
prices[i] = prices[i] * 2;
}
print(prices);
}[200, 500, 800]9. Finding a Position with indexOf
The reverse question — "at which index is this value?" — is answered by indexOf, just as
for strings in Lecture 008:
void main() {
var names = ['Ali', 'Sara', 'Zayan', 'Sara'];
print(names.indexOf('Sara'));
print(names.indexOf('Omar'));
}1
-1It returns the first match, or -1 when the value isn't there. Always check for -1
before using the result as an index. Searching a list properly is the topic of Lecture 042.
10. Nullable Elements vs a Nullable List
Where you put the ? matters:
List<int?>— the list always exists, but an element may benull.List<int>?— the elements are nevernull, but the whole list may be missing.
List<int>? savedMarks;
void main() {
List<int?> scores = [85, null, 78];
print(scores[1] ?? 0);
print(savedMarks?[0]);
print(savedMarks?.length ?? 0);
}0
null
0Reading from List<int?> gives an int?, so ?? supplies a default. On a List<int>?,
?[] (Lecture 014) reads only if the list exists — savedMarks was never given one, so it
is still null. Writing savedMarks[0] is an error:
Error: Operator '[]' cannot be called on 'List<int>?' because it is potentially null.11. A Real-World Example
void main() {
var students = ['Ali', 'Sara', 'Zayan'];
var marks = [72, 88, 64];
marks[2] = 69; // Zayan's paper was rechecked
for (var i = 0; i < students.length; i++) {
print('${students[i]}: ${marks[i]}');
}
var top = marks.indexOf(88);
print('Top student: ${students[top]}');
print('First: ${students.first}, last: ${students.last}');
}Ali: 72
Sara: 88
Zayan: 69
Top student: Sara
First: Ali, last: ZayanTwo lists line up by index: students[i] and marks[i] describe the same person. The
counting loop gives us i for both, and indexOf turns a mark back into a position.
Code Examples
Example 1 — Reading by Index
void main() {
var cities = ['Lahore', 'Karachi', 'Islamabad'];
print(cities[0]);
print(cities[2]);
}Lahore
IslamabadExample 2 — first, last, and length - 1
void main() {
var ages = [6, 18, 20, 35];
print(ages.first);
print(ages.last);
print(ages[ages.length - 1]);
}6
35
35Example 3 — Replacing an Element
void main() {
var names = ['Ali', 'Sara', 'Zayan'];
names[0] = 'Omar';
print(names);
}[Omar, Sara, Zayan]Example 4 — An Index from a Variable
void main() {
var days = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri'];
var today = 3;
print('Today: ${days[today]}');
print('Tomorrow: ${days[today + 1]}');
}Today: Thu
Tomorrow: FriExample 5 — Printing Index and Value
void main() {
var colors = ['red', 'green', 'blue'];
for (var i = 0; i < colors.length; i++) {
print('$i -> ${colors[i]}');
}
}0 -> red
1 -> green
2 -> blueExample 6 — indexOf
void main() {
var scores = [40, 75, 90, 75];
print(scores.indexOf(75));
print(scores.indexOf(100));
}1
-1Example 7 — Student Marks
void main() {
var marks = [80, 75, 85, 90];
marks[1] += 5;
var total = 0;
for (var i = 0; i < marks.length; i++) {
total += marks[i];
}
print('Marks: $marks');
print('Total: $total');
}Marks: [80, 80, 85, 90]
Total: 335How it works
marks[1] += 5turns the second mark75into80.- The loop reads
marks[0]tomarks[3]and adds each tototal.
Example 8 — Shopping Total
void main() {
var items = ['Notebook', 'Pen', 'Bag'];
var prices = [500, 50, 1500];
var quantities = [3, 4, 1];
var total = 0;
for (var i = 0; i < items.length; i++) {
var cost = prices[i] * quantities[i];
print('${items[i]}: $cost');
total += cost;
}
print('Total: $total');
}Notebook: 1500
Pen: 200
Bag: 1500
Total: 3200How it works
- Three lists line up by index: item
ihas priceiand quantityi. - One counting loop reads all three with the same
i.
Example 9 — Bank Balance History
void main() {
var balances = [1000.0, 1250.5, 1150.5];
print('Opening: ${balances.first}');
print('Current: ${balances.last}');
print('Change: ${balances.last - balances.first}');
}Opening: 1000.0
Current: 1150.5
Change: 150.5Example 10 — Temperature Conversion in Place
void main() {
var temperatures = [20.0, 25.0, 30.0];
for (var i = 0; i < temperatures.length; i++) {
temperatures[i] = temperatures[i] * 9 / 5 + 32;
}
print(temperatures);
}[68.0, 77.0, 86.0]How it works
- Each pass reads the Celsius value at index
iand stores the Fahrenheit value back in the same position. - A
for-inloop could not do this — assigning to its loop variable doesn't touch the list.
Common Beginner Mistakes
1. Treating the first element as index 1
void main() {
var names = ['Ali', 'Sara', 'Zayan'];
print(names[1]); // ✗ wanted Ali
}SaraNo error — just the wrong person. The first element is names[0].
2. Using length as an index
void main() {
var marks = [85, 92, 78];
// print(marks[marks.length]); // ✗ one past the end
}Unhandled exception:
RangeError (length): Invalid value: Not in inclusive range 0..2: 3The last index is length - 1, or simply use last.
3. Writing <= in the loop condition
void main() {
var marks = [85, 92, 78];
// for (var i = 0; i <= marks.length; i++) { // ✗ should be <
// print(marks[i]);
// }
}85
92
78
Unhandled exception:
RangeError (length): Invalid value: Not in inclusive range 0..2: 34. Trying to add with an index
void main() {
var marks = [85, 92, 78];
// marks[3] = 60; // ✗ there is no index 3 yet
}Unhandled exception:
RangeError (index): Invalid value: Not in inclusive range 0..2: 3Assigning by index only replaces. Adding comes in Lecture 041.
5. Calling first on an empty list
void main() {
var marks = <int>[];
// print(marks.first); // ✗ there is no first element
}Unhandled exception:
Bad state: No elementCheck isEmpty (Lecture 039) before reading first or last.
6. Using indexOf's result without checking for -1
void main() {
var names = ['Ali', 'Sara'];
var position = names.indexOf('Omar');
// print(names[position]); // ✗ position is -1
}Unhandled exception:
RangeError (length): Invalid value: Not in inclusive range 0..1: -17. Using a nullable element as a plain value
void main() {
List<int?> scores = [85, null, 78];
// int first = scores[0]; // ✗
}Error: A value of type 'int?' can't be assigned to a variable of type 'int'.Supply a default: int first = scores[0] ?? 0;.
Best Practices
- Remember that indexes start at
0and end atlength - 1. - Prefer
firstandlastover[0]and[length - 1]— but only on a non-empty list. - Write loop conditions as
i < list.length, never<=and never a fixed number. - Use
for-inwhen you only need values; use a counting loop when you need positions or want to change elements. - Check
indexOffor-1before using its result. - Put the
?where thenullcan really appear:List<int?>orList<int>?.
Mini Challenge
Sara's weekly temperatures are [22, 24, 19, 27, 25]. The third reading was entered wrongly
and should be 21. Fix it, then print every day as Day N: T and finally the first and last
readings.
Your program should print exactly:
Day 1: 22
Day 2: 24
Day 3: 21
Day 4: 27
Day 5: 25
First: 22, last: 25Try it yourself before opening the solution.
Show solution
void main() {
var temperatures = [22, 24, 19, 27, 25];
temperatures[2] = 21;
for (var i = 0; i < temperatures.length; i++) {
print('Day ${i + 1}: ${temperatures[i]}');
}
print('First: ${temperatures.first}, last: ${temperatures.last}');
}Day 1: 22
Day 2: 24
Day 3: 21
Day 4: 27
Day 5: 25
First: 22, last: 25How it works
- The third reading is at index
2, sotemperatures[2] = 21fixes it. - The loop prints
i + 1as the day number andtemperatures[i]as the value.
Practice Questions
Work through these in order — they run from beginner to application to challenge. Every question gives you exact values, so you can compare your output with the answers.
Beginner
- Create
var fruits = ['apple', 'banana', 'cherry'];and print the second fruit. - For the same list, print the last fruit three ways: with
last, withlength - 1, and with a fixed index. - Create
var marks = [60, 70, 80];, change the first mark to65, and print the list.
Application
-
Print every element of
['Ali', 'Sara', 'Zayan']asStudent 1: Aliand so on. -
Given
var prices = [100, 200, 300];, add50to every price with a counting loop and print the list. -
Given
var names = ['Ali', 'Sara', 'Zayan'];, print the index of'Zayan'and of'Omar'. -
This program crashes. Explain why in one sentence, then fix it:
void main() { var ages = [6, 18, 20]; print(ages[3]); } -
Create
List<int?> scores = [50, null, 90];and print the sum of all scores, countingnullas0.
Challenge
- Swap the first and last elements of
var names = ['Ali', 'Sara', 'Zayan'];and print the list. (Hint: you need a temporary variable.) - Two lists line up by index:
var products = ['Pen', 'Bag', 'Cap'];andvar stock = [12, 0, 5];. Look up'Bag'withindexOfand printBag: 0 in stock. Then do the same for'Hat', printingHat: not sold herewhen it isn't found.
Practice Answers
Question 1 — Solution
void main() {
var fruits = ['apple', 'banana', 'cherry'];
print(fruits[1]);
}bananaQuestion 2 — Solution
void main() {
var fruits = ['apple', 'banana', 'cherry'];
print(fruits.last);
print(fruits[fruits.length - 1]);
print(fruits[2]);
}cherry
cherry
cherryQuestion 3 — Solution
void main() {
var marks = [60, 70, 80];
marks[0] = 65;
print(marks);
}[65, 70, 80]Question 4 — Solution
void main() {
var students = ['Ali', 'Sara', 'Zayan'];
for (var i = 0; i < students.length; i++) {
print('Student ${i + 1}: ${students[i]}');
}
}Student 1: Ali
Student 2: Sara
Student 3: ZayanQuestion 5 — Solution
void main() {
var prices = [100, 200, 300];
for (var i = 0; i < prices.length; i++) {
prices[i] += 50;
}
print(prices);
}[150, 250, 350]Question 6 — Solution
void main() {
var names = ['Ali', 'Sara', 'Zayan'];
print(names.indexOf('Zayan'));
print(names.indexOf('Omar'));
}2
-1Question 7 — Solution
The list has 3 elements, so its indexes are 0..2 and ages[3] throws a RangeError.
void main() {
var ages = [6, 18, 20];
print(ages[2]);
}20print(ages.last); works too.
Question 8 — Solution
void main() {
List<int?> scores = [50, null, 90];
var total = 0;
for (var i = 0; i < scores.length; i++) {
total += scores[i] ?? 0;
}
print(total);
}140Question 9 — Solution
void main() {
var names = ['Ali', 'Sara', 'Zayan'];
var temp = names[0];
names[0] = names[names.length - 1];
names[names.length - 1] = temp;
print(names);
}[Zayan, Sara, Ali]Without temp, the first assignment would overwrite 'Ali' before it could be moved.
Question 10 — Solution
void main() {
var products = ['Pen', 'Bag', 'Cap'];
var stock = [12, 0, 5];
var bag = products.indexOf('Bag');
if (bag != -1) {
print('Bag: ${stock[bag]} in stock');
}
var hat = products.indexOf('Hat');
if (hat == -1) {
print('Hat: not sold here');
} else {
print('Hat: ${stock[hat]} in stock');
}
}Bag: 0 in stock
Hat: not sold hereQuick Revision
- What is the index of the first element of a list?
- What is the last valid index of a list with 5 elements?
- What do
firstandlastreturn? What happens on an empty list? - How do you replace the element at index
2? - What does
RangeError ... Not in inclusive range 0..2: 3tell you? - When do you need a counting
forloop instead offor-in? - What does
indexOfreturn when the value is missing? - What is the difference between
List<int?>andList<int>??
Key Takeaways
- Every element has an index; counting starts at
0and ends atlength - 1. list[i]reads an element;list[i] = valuereplaces it, checked against the element type.firstandlastread the ends; on an empty list they throwBad state: No element.- A missing index compiles but crashes with a
RangeError— both for reading and assigning. - Loop over positions with
for (var i = 0; i < list.length; i++); it can change elements. indexOfreturns the first matching index, or-1.List<int?>may holdnullelements;List<int>?may itself benull.
What's Next?
Lecture 041 — Adding & Removing Elements. Every list in this lecture kept its size: we
could read and replace, but marks[3] = 60 crashed. Real lists grow and shrink — a new
student joins, an item leaves the cart. Next we will add and remove elements and watch
length change as we do.