Going further · 18
2D lists (grids)
Grids of rows and columns: reading them, row and column sums, and neighbours inside the bounds.
A 2D list is a list of lists.grid[i][j] means column j of row i.
The example below reads a grid, finds the row and column sums, and prints the sum of each cell's neighbours.
r, c = map(int, input().split())grid = [list(map(int, input().split())) for _ in range(r)]print(*[sum(row) for row in grid])print(*[sum(grid[i][j] for i in range(r)) for j in range(c)])moves = [(-1, 0), (1, 0), (0, -1), (0, 1)]near = [[0] * c for _ in range(r)]for i in range(r): for j in range(c): for di, dj in moves: ni, nj = i + di, j + dj if 0 <= ni < r and 0 <= nj < c: near[i][j] += grid[ni][nj]for row in near: print(*row)const [[r, c], ...grid] = require("fs").readFileSync(0, "utf8").trim().split("\n").map((l) => l.trim().split(/\s+/).map(Number));console.log(grid.map((row) => row.reduce((a, b) => a + b, 0)).join(" "));const colSums = Array.from({ length: c }, (_, j) => grid.reduce((s, row) => s + row[j], 0));console.log(colSums.join(" "));const moves = [[-1, 0], [1, 0], [0, -1], [0, 1]];const near = Array.from({ length: r }, () => new Array(c).fill(0));for (let i = 0; i < r; i++) { for (let j = 0; j < c; j++) { for (const [di, dj] of moves) { const ni = i + di, nj = j + dj; if (ni >= 0 && ni < r && nj >= 0 && nj < c) near[i][j] += grid[ni][nj]; } }}for (const row of near) console.log(row.join(" "));import { readFileSync } from "node:fs";const [[r, c], ...grid]: number[][] = readFileSync(0, "utf8").trim().split("\n").map((l) => l.trim().split(/\s+/).map(Number));console.log(grid.map((row) => row.reduce((a, b) => a + b, 0)).join(" "));const colSums: number[] = Array.from({ length: c }, (_, j) => grid.reduce((s, row) => s + row[j], 0));console.log(colSums.join(" "));const moves: [number, number][] = [[-1, 0], [1, 0], [0, -1], [0, 1]];const near: number[][] = Array.from({ length: r }, () => new Array<number>(c).fill(0));for (let i = 0; i < r; i++) { for (let j = 0; j < c; j++) { for (const [di, dj] of moves) { const ni = i + di, nj = j + dj; if (ni >= 0 && ni < r && nj >= 0 && nj < c) near[i][j] += grid[ni][nj]; } }}for (const row of near) console.log(row.join(" "));import java.util.Scanner; public class Main { static void print(int[] a) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < a.length; i++) sb.append(i > 0 ? " " : "").append(a[i]); System.out.println(sb); } public static void main(String[] args) { Scanner sc = new Scanner(System.in); int r = sc.nextInt(), c = sc.nextInt(); int[][] grid = new int[r][c]; for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) grid[i][j] = sc.nextInt(); int[] rowSums = new int[r], colSums = new int[c]; for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) { rowSums[i] += grid[i][j]; colSums[j] += grid[i][j]; } print(rowSums); print(colSums); int[] di = {-1, 1, 0, 0}, dj = {0, 0, -1, 1}; for (int i = 0; i < r; i++) { int[] near = new int[c]; for (int j = 0; j < c; j++) for (int k = 0; k < 4; k++) { int ni = i + di[k], nj = j + dj[k]; if (ni >= 0 && ni < r && nj >= 0 && nj < c) near[j] += grid[ni][nj]; } print(near); } }}using System;using System.Linq; class Program{ static void Main() { int[] rc = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); int r = rc[0], c = rc[1]; int[,] grid = new int[r, c]; for (int i = 0; i < r; i++) { int[] row = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray(); for (int j = 0; j < c; j++) grid[i, j] = row[j]; } Console.WriteLine(string.Join(" ", Enumerable.Range(0, r).Select(i => Enumerable.Range(0, c).Sum(j => grid[i, j])))); Console.WriteLine(string.Join(" ", Enumerable.Range(0, c).Select(j => Enumerable.Range(0, r).Sum(i => grid[i, j])))); int[] di = { -1, 1, 0, 0 }, dj = { 0, 0, -1, 1 }; for (int i = 0; i < r; i++) { int[] near = new int[c]; for (int j = 0; j < c; j++) for (int k = 0; k < 4; k++) { int ni = i + di[k], nj = j + dj[k]; if (ni >= 0 && ni < r && nj >= 0 && nj < c) near[j] += grid[ni, nj]; } Console.WriteLine(string.Join(" ", near)); } }}#include <iostream>#include <vector> void print(const std::vector<int>& v) { for (size_t i = 0; i < v.size(); i++) std::cout << (i > 0 ? " " : "") << v[i]; std::cout << '\n';} int main() { int r, c; std::cin >> r >> c; std::vector<std::vector<int>> grid(r, std::vector<int>(c)); for (auto& row : grid) for (int& x : row) std::cin >> x; std::vector<int> rowSums(r, 0), colSums(c, 0); for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) { rowSums[i] += grid[i][j]; colSums[j] += grid[i][j]; } print(rowSums); print(colSums); const int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1}; for (int i = 0; i < r; i++) { std::vector<int> near(c, 0); for (int j = 0; j < c; j++) for (int k = 0; k < 4; k++) { int ni = i + di[k], nj = j + dj[k]; if (ni >= 0 && ni < r && nj >= 0 && nj < c) near[j] += grid[ni][nj]; } print(near); }}#include <stdio.h> #define MAX 100 int grid[MAX][MAX]; void print(const int *a, int n) { for (int i = 0; i < n; i++) printf(i > 0 ? " %d" : "%d", a[i]); printf("\n");} int main(void) { int r, c, rowSums[MAX] = {0}, colSums[MAX] = {0}; scanf("%d %d", &r, &c); for (int i = 0; i < r; i++) for (int j = 0; j < c; j++) { scanf("%d", &grid[i][j]); rowSums[i] += grid[i][j]; colSums[j] += grid[i][j]; } print(rowSums, r); print(colSums, c); const int di[] = {-1, 1, 0, 0}, dj[] = {0, 0, -1, 1}; for (int i = 0; i < r; i++) { int near[MAX] = {0}; for (int j = 0; j < c; j++) for (int k = 0; k < 4; k++) { int ni = i + di[k], nj = j + dj[k]; if (ni >= 0 && ni < r && nj >= 0 && nj < c) near[j] += grid[ni][nj]; } print(near, c); } return 0;}rc = Console.ReadNumbers();r = rc[0];c = rc[1];grid = [];for (i = 0; i < r; i++){ grid.Add(Console.ReadNumbers());}rowSums = NewList(r, 0);colSums = NewList(c, 0);for (i = 0; i < r; i++){ for (j = 0; j < c; j++) { rowSums[i] += grid[i][j]; colSums[j] += grid[i][j]; }}Console.WriteLine(rowSums);Console.WriteLine(colSums);di = [-1, 1, 0, 0];dj = [0, 0, -1, 1];for (i = 0; i < r; i++){ near = NewList(c, 0); for (j = 0; j < c; j++) { for (k = 0; k < 4; k++) { ni = i + di[k]; nj = j + dj[k]; if (ni >= 0 && ni < r && nj >= 0 && nj < c) { near[j] += grid[ni][nj]; } } } Console.WriteLine(near);}3 4 1 2 3 4 5 6 7 8 9 10 11 12
10 26 42 15 18 21 24 7 10 13 11 16 24 28 23 15 26 29 19
Key points
- To visit every cell, put a loop over columns inside a loop over rows (a nested loop).
- Row sums add up the cells of each row; column sums walk down each column.
You can also add intorowSums[i]andcolSums[j]together in one pass. - For neighbours (up, down, left, right), keep the directions in lists such as
di = [-1, 1, 0, 0]anddj = [0, 0, -1, 1]and loop over them.
The code gets short. - On the edge a neighbour falls outside.
Always check0 <= ni < rand0 <= nj < cbefore reading, including the negative side. - Each row must be created separately.
If the same row goes in several times, changing one cell changes every row.
How each language writes it
| Python | [[0] * c for _ in range(r)].grid[-1] is not an error but the last row |
|---|---|
| JavaScript | Array.from({ length: r }, () => new Array(c).fill(0)).A cell outside is undefined; reading a cell of a row outside throws TypeError |
| TypeScript | Same as JavaScript. The type is number[][] |
| Java | new int[r][c] — filled with zeros.Out of range: ArrayIndexOutOfBoundsException |
| C# | Two kinds: the rectangular array int[r, c] (read with grid[i, j]) and the jagged array of arrays int[r][].Out of range: IndexOutOfRangeException |
| C++ | vector<vector<int>>(r, vector<int>(c)).[] does not check the range |
| C | Fix the size in advance, like int grid[100][100], and use only the top-left part.Reading out of range says nothing |
| Craykon | Build it row by row with grid.Add(Console.ReadNumbers()), and make a row of c zeros with NewList(c, 0).Out of range stops with an error saying the list only has items 0 to 3 |
Common mistakes
Reading the top row's upper neighbour without a checkPython
grid = [[1, 2], [3, 4]]
i, j = 0, 0
print(grid[i - 1][j])→ 3 — grid[-1] is the last row, so it quietly reads from the bottom row
Check the negative side too: 0 <= ni < r.
Skipping the range checkJavaScript · TypeScript · C · C++
const grid = [[1, 2], [3, 4]];
console.log(1 + grid[0][2]);
console.log(grid[2][0]);→ Prints NaN, then the next line stops with a TypeError. C and C++ silently read the next row or unrelated memory
Check 0 <= ni && ni < r && 0 <= nj && nj < c before reading.
Java, C# and Craykon stop with an index error.
How languages differ
Python
JavaScript
Python
[[0] * c] * r makes r references to one and the same row: after g = [[0] * 3] * 2; g[0][0] = 5 you get [[5, 0, 0], [5, 0, 0]].JavaScript
new Array(r).fill(new Array(c).fill(0)) does the same, so always create each row separately.