Watch the video (9 min)
On this page24 sections
  1. Prerequisites
  2. Connection With Previous Lectures
  3. Learning Objectives
  4. 1. What Is a List?
  5. 2. Creating a List
  6. 3. Every List Has a Type
  7. 4. Writing the List Type Yourself
  8. 5. The Element Type Is Checked
  9. 6. How Many Elements? length
  10. 7. Empty Lists
  11. 8. isEmpty and isNotEmpty
  12. 9. Looping Over a List
  13. 10. Mixed Types — and Why to Avoid Them
  14. 11. Passing a List to a Function
  15. 12. A Real-World Example
  16. Code Examples
  17. Common Beginner Mistakes
  18. Best Practices
  19. Mini Challenge
  20. Practice Questions
  21. Practice Answers
  22. Quick Revision
  23. Key Takeaways
  24. What's Next?

Lecture 39 — Introduction to Lists

Category7 — Lists
Lecture039 of 140
Estimated video length9 min
TargetDart 3.12.2
LevelBeginner

One variable holds one value, so thirty students would need thirty variables. A list keeps many values, in order, under one name.

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 004–038:

  • variables, var, and explicit types (Lectures 004–005)
  • dynamic and Object (Lecture 011)
  • if statements and += (Lectures 017, 022)
  • for-in loops over values in square brackets (Lecture 027)
  • functions with parameters and return values (Lecture 031)

Connection With Previous Lectures

Here is Ali's report with the tools from Lecture 004:

dart
void main() {
  int math = 80;
  int science = 75;
  int english = 85;
  print(math + science + english);
}
output
240

Three subjects, three variables. Add a fourth subject and you need a fourth variable and a changed total line. In Lecture 027 we looped over [85, 92, 78] without asking what that bracketed group really is. Today we answer that: it is a list, and it has a type, a size, and rules of its own.


Learning Objectives

By the end of this lecture you will be able to:

  • Understand what a list is and why programs need one
  • Create lists of int, double, String, and bool values
  • Read and write list types such as List<int> and List<String>
  • Create an empty list that still has a proper type
  • Use length, isEmpty, and isNotEmpty
  • Loop over a list with for-in to total, count, and print its values
  • Pass a list to a function
  • Explain why lists of mixed types should be avoided

1. What Is a List?

A list is an ordered group of values stored in one variable.

Analogy — think of a shopping list on paper. It has one title at the top, and below it the items, one after another, in the order you wrote them.

dart
void main() {
  var marks = [80, 75, 85];
  print(marks);
}
output
[80, 75, 85]

The values inside a list are called its elements. marks holds three elements.


2. Creating a List

Write the elements inside square brackets, separated by commas. The order you write is the order Dart keeps, and duplicates are allowed:

dart
void main() {
  var temperatures = [21.5, 25.0, 21.5, 19.0];
  print(temperatures);
}
output
[21.5, 25.0, 21.5, 19.0]

print shows the whole list, brackets included. A list written straight into the code like this is called a list literal.


3. Every List Has a Type

A list knows what kind of elements it holds. runtimeType (Lecture 010) shows it:

dart
void main() {
  var marks = [80, 75, 85];
  var names = ['Ali', 'Sara', 'Zayan'];
  print(marks.runtimeType);
  print(names.runtimeType);
}
output
List<int>
List<String>

Read List<int> as "a list of int". The type inside the angle brackets < > is the element type. This feature is called generics — we will study it properly in Lecture 072 — Generics Fundamentals. For now, List<something> is all you need.


4. Writing the List Type Yourself

var lets Dart infer the type, just as in Lecture 005. You can also write it explicitly:

dart
void main() {
  List<int> marks = [80, 75, 85];
  List<String> names = ['Ali', 'Sara'];
  List<double> prices = [4.5, 12];
  print(marks);
  print(names);
  print(prices);
}
output
[80, 75, 85]
[Ali, Sara]
[4.5, 12.0]

Like a double variable (Lecture 004), a List<double> stores the whole number 12 as 12.0.


5. The Element Type Is Checked

Once the type says int, every element must be an int:

dart
void main() {
  // List<int> marks = [85, 'ninety', 78]; // ✗
}
output
Error: A value of type 'String' can't be assigned to a variable of type 'int'.
  List<int> marks = [85, 'ninety', 78];
                         ^

Dart points at the exact element that doesn't belong — before the program even runs.


6. How Many Elements? length

length gives the number of elements — the same property you used on strings in Lecture 008:

dart
void main() {
  var names = ['Ali', 'Sara', 'Zayan'];
  print(names.length);
}
output
3

length is a property, not a function: no () after it.


7. Empty Lists

A list can start with no elements. Because [] alone gives Dart nothing to infer from, state the element type, either on the variable or in front of the brackets:

dart
void main() {
  List<String> guests = [];
  var scores = <int>[];
  print(guests);
  print(scores.length);
  print(scores.runtimeType);
}
output
[]
0
List<int>

Both lines create an empty list that still knows its element type. Filling it comes in Lecture 041 — Adding & Removing Elements.


8. isEmpty and isNotEmpty

These two bool properties answer "is there anything in here?":

dart
void main() {
  List<String> guests = [];
  var names = ['Ali', 'Sara'];
  print(guests.isEmpty);
  print(names.isEmpty);
  print(names.isNotEmpty);
}
output
true
false
true

guests.isEmpty reads better than guests.length == 0, and means the same.


9. Looping Over a List

The for-in loop from Lecture 027 visits each element in order. Combine it with += to build a total:

dart
void main() {
  List<int> marks = [80, 75, 85];
  var total = 0;
  for (final mark in marks) {
    total += mark;
  }
  print('Total: $total');
  print('Subjects: ${marks.length}');
}
output
Total: 240
Subjects: 3

Add a fourth mark to the list and the total updates — no new variable, no edited line.


10. Mixed Types — and Why to Avoid Them

Dart allows a list with different kinds of values. It infers the closest type they share:

dart
void main() {
  var mixed = [85, 'Ali', true];
  print(mixed.runtimeType);
}
output
List<Object>

Object (Lecture 011) fits every value, so you can only do what works for every value. Math is not one of those things:

dart
void main() {
  var mixed = [85, 'Ali', true];
  for (final item in mixed) {
    // print(item * 2); // ✗
  }
}
output
Error: The operator '*' isn't defined for the type 'Object'.

Keep one kind of value per list. Related values of different kinds — a name with its mark — belong in a record or a class, which come later in the course.


11. Passing a List to a Function

A list type works as a parameter type, like any other (Lecture 031):

dart
int sumOf(List<int> numbers) {
  var total = 0;
  for (final number in numbers) {
    total += number;
  }
  return total;
}

void main() {
  print(sumOf([80, 75, 85]));
  print(sumOf([]));
}
output
240
0

The parameter type List<int> tells Dart what [] must be, so even the empty list is a proper List<int>.


12. A Real-World Example

dart
double average(List<double> values) {
  var total = 0.0;
  for (final value in values) {
    total += value;
  }
  return total / values.length;
}

void main() {
  List<double> temperatures = [21.5, 25.0, 19.0, 27.5];
  if (temperatures.isEmpty) {
    print('No readings yet');
  } else {
    print('Readings: ${temperatures.length}');
    print('Average: ${average(temperatures)}');
  }
}
output
Readings: 4
Average: 23.25

One typed list, a check that it isn't empty, a loop inside a function, and length — the whole lecture in one program.


Code Examples

Example 1 — A List of Numbers

dart
void main() {
  var marks = [90, 85, 77];
  print(marks);
}
output
[90, 85, 77]

Example 2 — A List of Strings

dart
void main() {
  List<String> names = ['Ali', 'Sara', 'Zayan'];
  print(names);
  print(names.length);
}
output
[Ali, Sara, Zayan]
3

Example 3 — A List of Booleans

dart
void main() {
  List<bool> attendance = [true, false, true, true];
  print(attendance);
}
output
[true, false, true, true]

Example 4 — Seeing the Type

dart
void main() {
  var prices = [4.5, 12.0];
  var words = ['tea', 'milk'];
  print(prices.runtimeType);
  print(words.runtimeType);
}
output
List<double>
List<String>

Example 5 — An Empty List

dart
void main() {
  var orders = <String>[];
  print(orders);
  print(orders.length);
  print(orders.isEmpty);
}
output
[]
0
true

Example 6 — Greeting Everyone

dart
void main() {
  var names = ['Ali', 'Sara', 'Zayan'];
  for (final name in names) {
    print('Hello, $name!');
  }
}
output
Hello, Ali!
Hello, Sara!
Hello, Zayan!

Example 7 — Student Marks

dart
void main() {
  List<int> marks = [80, 75, 85, 90];
  var total = 0;
  for (final mark in marks) {
    total += mark;
  }
  print('Total: $total');
  print('Average: ${total / marks.length}');
}
output
Total: 330
Average: 82.5

How it works

  1. The loop adds each mark into total, giving 330.
  2. marks.length is 4, so the average is 330 / 4.
  3. / always produces a double, so the average prints 82.5.

Example 8 — Shopping Total

dart
void main() {
  List<double> prices = [250, 120.5, 80];
  var total = 0.0;
  for (final price in prices) {
    total += price;
  }
  print('Items: ${prices.length}');
  print('Total: $total');
}
output
Items: 3
Total: 450.5

How it works

  1. 250 and 80 are stored as 250.0 and 80.0 because the list is List<double>.
  2. total starts as 0.0, so it is a double and can take each price.

Example 9 — Bank Deposits

dart
void main() {
  var balance = 1000;
  List<int> deposits = [200, 50, 300];
  for (final deposit in deposits) {
    balance += deposit;
  }
  print('Deposits: ${deposits.length}');
  print('Balance: $balance');
}
output
Deposits: 3
Balance: 1550

How it works

  1. balance starts at 1000.
  2. Each deposit is added: 1200, 1250, 1550.

Example 10 — Counting Hot Days

dart
void main() {
  List<double> temperatures = [21.5, 31.0, 28.0, 33.5, 19.0];
  var hotDays = 0;
  for (final temperature in temperatures) {
    if (temperature > 30) {
      hotDays++;
    }
  }
  print('Hot days: $hotDays of ${temperatures.length}');
}
output
Hot days: 2 of 5

How it works

  1. The loop checks every temperature with if.
  2. Only 31.0 and 33.5 are above 30, so hotDays ends at 2.

Common Beginner Mistakes

1. An element of the wrong type

dart
void main() {
  // List<int> prices = [4.5, 12]; // ✗
}
output
Error: A value of type 'double' can't be assigned to a variable of type 'int'.

Use List<double> for prices with decimals.

2. Empty brackets with no type

dart
void main() {
  var orders = [];
  print(orders.runtimeType);
}
output
List<dynamic>

No error — which is the problem. dynamic switches type checking off (Lecture 011). Write <String>[] or List<String> orders = [];.

3. Calling length like a function

dart
void main() {
  var marks = [85, 92, 78];
  // print(marks.length()); // ✗
}
output
Error: 'length' isn't a function or method and can't be invoked.

Write marks.length, without brackets.

4. Round brackets instead of square brackets

dart
void main() {
  // List<int> scores = (85, 92); // ✗
}
output
Error: A value of type '(int, int)' can't be assigned to a variable of type 'List<int>'.

Round brackets make a record, a different thing (Lecture 076). Lists use [ ].

5. Mixing kinds of values

[85, 'Ali', true] compiles, but becomes a List<Object> you can't calculate with. Keep one kind of value per list.


Best Practices

  • Give lists plural names (marks, names) and loop variables the singular (mark).
  • Keep one kind of value per list.
  • Always give an empty list a type: <int>[] or List<int> x = [];.
  • Use var when the elements make the type obvious; write List<…> when it states your intent better, such as List<double> for prices.
  • Prefer isEmpty / isNotEmpty over comparing length with 0.
  • Use final for the loop variable when you only read each element.

Mini Challenge

Store Sara's marks [70, 88, 92, 65] in a List<int>. Print how many marks there are, the total, and how many marks are 80 or more.

Your program should print exactly:

output
Marks: 4
Total: 315
80 or more: 2

Try it yourself before opening the solution.

Show solution
dart
void main() {
  List<int> marks = [70, 88, 92, 65];
  var total = 0;
  var high = 0;
  for (final mark in marks) {
    total += mark;
    if (mark >= 80) {
      high++;
    }
  }
  print('Marks: ${marks.length}');
  print('Total: $total');
  print('80 or more: $high');
}
output
Marks: 4
Total: 315
80 or more: 2

One loop does both jobs: every mark joins the total, and only high marks bump the counter.


Practice Questions

Work through these in order — they run from beginner to application to challenge.

Beginner

  1. Create a list of the cities 'Lahore', 'Karachi', 'Quetta' and print it.
  2. Create a List<int> of 10, 20, 30 and print its length.
  3. Create an empty List<double> named readings, then print its isEmpty.
  4. Print the runtimeType of [true, false].

Application

  1. Print each name in ['Ali', 'Sara', 'Zayan'] as Student: <name>.
  2. Total the prices [120, 80, 45] and print Total: 245.
  3. Count how many numbers in [5, 12, 8, 20, 3] are greater than 7.
  4. Write a function int countOf(List<String> items) that returns the number of items. Call it with ['tea', 'milk', 'bread'] and print the result.

Challenge

  1. For the temperatures [18.5, 22.0, 25.5], print the number of readings and the average.
  2. Write a function void report(List<int> marks) that prints No marks for an empty list, and otherwise prints Total: <total>. Call it with [] and with [60, 70].

Practice Answers

Question 1 — Solution

dart
void main() {
  var cities = ['Lahore', 'Karachi', 'Quetta'];
  print(cities);
}
output
[Lahore, Karachi, Quetta]

Question 2 — Solution

dart
void main() {
  List<int> numbers = [10, 20, 30];
  print(numbers.length);
}
output
3

Question 3 — Solution

dart
void main() {
  List<double> readings = [];
  print(readings.isEmpty);
}
output
true

Question 4 — Solution

dart
void main() {
  print([true, false].runtimeType);
}
output
List<bool>

Question 5 — Solution

dart
void main() {
  var names = ['Ali', 'Sara', 'Zayan'];
  for (final name in names) {
    print('Student: $name');
  }
}
output
Student: Ali
Student: Sara
Student: Zayan

Question 6 — Solution

dart
void main() {
  var prices = [120, 80, 45];
  var total = 0;
  for (final price in prices) {
    total += price;
  }
  print('Total: $total');
}
output
Total: 245

Question 7 — Solution

dart
void main() {
  var numbers = [5, 12, 8, 20, 3];
  var count = 0;
  for (final number in numbers) {
    if (number > 7) {
      count++;
    }
  }
  print(count);
}
output
3

Question 8 — Solution

dart
int countOf(List<String> items) {
  return items.length;
}

void main() {
  print(countOf(['tea', 'milk', 'bread']));
}
output
3

Question 9 — Solution

dart
void main() {
  var temperatures = [18.5, 22.0, 25.5];
  var total = 0.0;
  for (final temperature in temperatures) {
    total += temperature;
  }
  print('Readings: ${temperatures.length}');
  print('Average: ${total / temperatures.length}');
}
output
Readings: 3
Average: 22.0

Question 10 — Solution

dart
void report(List<int> marks) {
  if (marks.isEmpty) {
    print('No marks');
    return;
  }
  var total = 0;
  for (final mark in marks) {
    total += mark;
  }
  print('Total: $total');
}

void main() {
  report([]);
  report([60, 70]);
}
output
No marks
Total: 130

The early return (Lecture 031) handles the empty case first.


Quick Revision

  1. What is a list?
  2. What are the values inside a list called?
  3. How do you read List<String> aloud?
  4. What does var x = []; create, and why is it a problem?
  5. What is the difference between isEmpty and isNotEmpty?
  6. Why does [85, 'Ali', true] become a List<Object>?

Key Takeaways

  • A list is an ordered group of values, called elements, under one name.
  • Create one with square brackets: [80, 75, 85]. Order is kept; duplicates are allowed.
  • List<int> means "a list of int"; the element type is checked on every element.
  • Give empty lists a type: List<int> x = []; or <int>[] — plain [] is List<dynamic>.
  • length counts elements; isEmpty and isNotEmpty answer "anything in here?"
  • for-in visits every element in order — ideal for totals and counts.
  • A list type works as a function parameter, like any other type.
  • Mixed lists become List<Object>; keep one kind of value per list.

What's Next?

Lecture 040 — List Elements & Indexes. So far we have treated a list as a whole: printed it, counted it, looped over it. Next we reach inside — reading one element by its position, changing it, and avoiding the classic "index out of range" crash.


Video lecture

Subscribe
Placeholder video — the real recording isn't linked yet.