How Do You Build and Traverse a 2D List?



☰

开始北极星测评

Python 学习笔记

How Do You Build and Traverse a 2D List?

Learn how to build, index, read, and traverse Python 2D lists while avoiding shared-row aliasing mistakes.

Python 学习笔记

Python 二维列表怎么创建和遍历?

讲清 Python 二维列表的创建、索引、读入与遍历,并避开多行共享同一个列表的陷阱。

分享这篇文章

复制链接、使用手机分享、用微信扫码,或通过邮件发送。




邮箱

Maps, seating charts, score tables — many problems hand you a table instead of a single list. Beginners often get stuck here: the data clearly has rows and columns, but where does it go in the program? A 2D list is not mysterious at all: it is a "list that holds several rows," and each row is itself a list. This article uses one small 2-by-3 example to show how to build one, read a cell, and visit every cell.

A Common Mistake

Look at this tempting shortcut first:

grid = [[0] * 3] * 2
grid[0][1] = 9
print(grid)

Many people expect [[0, 9, 0], [0, 0, 0]], but the real output is:

[[0, 9, 0], [0, 9, 0]]

We only changed the first row, so why did both rows change? Because [[0] * 3] * 2 copies not "two rows" but "two references to the same row object." The two rows are the same row, so editing any cell shows up in both.

Two more mistakes happen when reading a table. Forgetting int(): without it, every cell stays a string, and addition turns into string joining. Swapping the indexes: grid[1][2] is not "row one, column two" in everyday counting — it is the row numbered 1 and the column numbered 2, both counted from 0. Remember the order: grid[row][col], row first, column second.

The Core Idea

A 2D list is a list of lists. Store this seating chart in a program:

col 0 col 1 col 2
row 0 4 7 2
row 1 9 1 5

It looks like this:

grid = [
    [4, 7, 2],
    [9, 1, 5],
]

Why two indexes? Because to find a person you first say which row they sit in (row), then which seat in that row (col). Read one cell with grid[row][col]: grid[1][2] is row 1, column 2, which is 5; grid[0][0] is the top-left corner, which is 4. For the whole table, len(grid) is the number of rows and len(grid[0]) is the number of columns.

The Recommended Way to Build One

In contests, a table usually comes from input: the first line is the number of rows r, the second line is the number of columns c, followed by r lines of c numbers each.

r = int(input())
c = int(input())
grid = []

for _ in range(r):
    row = [int(x) for x in input().split()]
    grid.append(row)

Read one line, convert to numbers, append one row — repeat r times and the grid is ready. If you prefer to create an empty table first and fill it later, the correct pattern is:

grid = [[0] * c for _ in range(r)]

The for _ in range(r) part makes every iteration produce a fresh list — that is the key, and it is exactly the fix for the shared-row trap above.

Visiting Every Cell

The outer loop controls rows, the inner loop controls columns, and together they visit each cell exactly once:

grid = [
    [4, 7, 2],
    [9, 1, 5],
]

for row in range(len(grid)):
    for col in range(len(grid[row])):
        print(row, col, grid[row][col])
0 0 4
0 1 7
0 2 2
1 0 9
1 1 1
1 2 5

Finish the three cells of row 0 first, then move into row 1 — left to right, top to bottom, like reading a book. Once traversal is in place, summaries follow. To print the sum of each row:

for row in grid:
    row_sum = 0
    for value in row:
        row_sum += value
    print(row_sum)
13
15

For column sums, do it the other way around: fix one column, then add it from top to bottom, giving 13, 8, 7. Watch where you reset the local row_sum — it must be cleared before starting each row, or the numbers merge into one running total.

Updating and Counting Cells

Updates and counts are just small variations of traversal. Add one to every cell:

for row in range(len(grid)):
    for col in range(len(grid[row])):
        grid[row][col] += 1

Counting "how many cells equal the target" is the same walk with a counter that increases on every match:

grid = [
    [4, 7, 2],
    [9, 1, 5],
]

target = 7
count = 0

for row in range(len(grid)):
    for col in range(len(grid[row])):
        if grid[row][col] == target:
            count += 1

print(count)
1

These are the same moves behind grid-style problems: a snail's path across cells, harvest counts on a farm, or triangular fields.

Compare the Options

Pattern When to use it Watch out
[[0] * c] * r Looks quick All rows share one object; editing one cell changes every row. Do not use it.
[[0] * c for _ in range(r)] Build first, fill later Each row is independent. Recommended.
Read one row, then append it Contest input Remember int() for numeric cells, or they stay strings.
Fix row and vary col / fix col and vary row Row sums / column sums Reset the accumulator before the loop it belongs to.

Practice

  1. Basic: build [[4, 7, 2], [9, 1, 5]] and print grid[1][2]. (Answer: 5)
  2. Variation: read r, c, and a numeric table, then print the sum of each row.
  3. Challenge: print the sum of each column, then the total of the whole table.

One-Sentence Takeaway

A 2D list is a list of lists: use grid[row][col], row before column, and make every row a fresh list.

If this article helped you sort out indexes and traversal, save it and practice along. To work on more grid-style problems, visit the Python Learning Notes channel on our website and follow the series step by step.

地图、座位表、成绩单——很多题目给你的数据不是一个列表,而是一张表格。新手常常卡在这里:格子明明有行有列,程序里却不知道往哪放。其实二维列表并不神秘:它就是一个「装着若干行的列表」,而每一行本身又是一个列表。这篇用一个 2 行 3 列的小例子,讲清怎么创建、怎么取值、怎么一格一格遍历。

常见错误

先看看这个看似方便的写法:

grid = [[0] * 3] * 2
grid[0][1] = 9
print(grid)

很多人以为会打印 [[0, 9, 0], [0, 0, 0]],实际结果却是:

[[0, 9, 0], [0, 9, 0]]

只改了第一行,为什么两行都变了?因为 [[0] * 3] * 2 复制的不是「两行」,而是「同一个行对象的两份引用」——两行其实是同一行。改任何一格,两行一起变。

读表格时还有两个高频错误。一是忘记把输入转成数字:不加 int(),格子全是字符串,做加法会变成拼字符串。二是行列下标搞混:grid[1][2] 不是「第 1 行第 2 列」的自然说法,而是「从 0 数起的第 1 行、第 2 列」。记住顺序——grid[row][col],先行后列。

核心概念

二维列表就是列表套列表。把这张座位表存进程序:

第 0 列 第 1 列 第 2 列
第 0 行 4 7 2
第 1 行 9 1 5

写出来就是:

grid = [
    [4, 7, 2],
    [9, 1, 5],
]

为什么要两个下标?因为找一个人,要先说他坐第几排(row),再说他在这一排的第几个位置(col)。取一个格子就写 grid[row][col]:grid[1][2] 是第 1 行的第 2 列,也就是 5;grid[0][0] 是左上角,也就是 4。两张表拼在一起,len(grid) 是行数,len(grid[0]) 是列数。

严格说,每行的长度可以不一样,二维列表并不强迫表格整齐。但竞赛里的输入都保证是矩形表格,所以按题目给的行列数处理就好,别自己额外加判断。

推荐写法

竞赛里的表格一般从输入读进来:第一行是行数 r,第二行是列数 c,接下来 r 行,每行 c 个数。

r = int(input())
c = int(input())
grid = []

for _ in range(r):
    row = [int(x) for x in input().split()]
    grid.append(row)

读一行、转数字、append 一行,循环 r 次,表格就建好了。如果打算先建好空表再慢慢填,正确写法是:

grid = [[0] * c for _ in range(r)]

for _ in range(r) 会让每一轮都生成一个新列表,这才是关键——它正是前面那个共享行陷阱的解法。

遍历所有格子

外层循环管行,内层循环管列,两个循环合起来把每个格子恰好走一遍:

grid = [
    [4, 7, 2],
    [9, 1, 5],
]

for row in range(len(grid)):
    for col in range(len(grid[row])):
        print(row, col, grid[row][col])
0 0 4
0 1 7
0 2 2
1 0 9
1 1 1
1 2 5

先走完第 0 行的三格,再走进第 1 行——像读书一样从左到右、从上到下。交换两层循环的顺序也能走完每个格子,但按行优先最不容易把自己绕晕。遍历有了,统计就顺了。比如分别求每一行的和:

for row in grid:
    row_sum = 0
    for value in row:
        row_sum += value
    print(row_sum)
13
15

求列和就反过来:先固定一列,再把这一列从上到下加一遍,结果是 13、8、7。注意局部变量 row_sum 要在「进入每一行之前」清零;清错了位置,数字就会累加到一起。

改格子、数格子

更新和计数只是遍历的小变种。让所有格子的值加一:

for row in range(len(grid)):
    for col in range(len(grid[row])):
        grid[row][col] += 1

数「有多少格等于目标值」也一样走一遍,碰到相等就让计数器加一:

grid = [
    [4, 7, 2],
    [9, 1, 5],
]

target = 7
count = 0

for row in range(len(grid)):
    for col in range(len(grid[row])):
        if grid[row][col] == target:
            count += 1

print(count)
1

这些正是地图类、网格类题目——比如蜗牛爬过的格子、农田收成、三角形田地——背后的同一套动作。

对比一下

写法 适合情况 注意点
[[0] * c] * r 看起来省事 所有行共享同一对象,改一格全变,不要用
[[0] * c for _ in range(r) 先建表、后填值 每行独立,推荐
读一行 append 一行 竞赛输入 数字格子记得 int(),否则是字符串
固定 row 变 col / 固定 col 变 row 求行和 / 求列和 求和的变量要在正确的循环前清零

小练习

  1. 基础题:建出 [[4, 7, 2], [9, 1, 5]],打印 grid[1][2]。(答案:5)
  2. 变式题:读入 r、c 和一个数字表格,输出每一行的和。
  3. 挑战题:输出每一列的和,再输出整张表格的总和。

一句话记住

二维列表就是列表套列表:grid[row][col],先行后列,一行一个新列表。

如果这篇帮你理顺了下标和遍历,欢迎收藏起来照着练。想动手做更多表格类的题目,可以到官网 Python Learning Notes 频道,跟着系列笔记一步一步来。

有问题或建议?

如果你对本文有疑问,或希望提出改进建议,请给我们发送私密留言。

发送反馈

有问题或建议?

如果你对本文有疑问,或希望提出改进建议,请给我们发送私密留言。

发送反馈

Back to Python Learning Notes
返回Python 学习笔记

滚动至顶部