坐标移动与条件判断详解
你好呀!如果你之前完全没接触过编程,这篇文章就是为你准备的。我会把这两道作业的代码 一行一行拆开 ,用生活中的例子讲清楚。看完你会发现:编程其实没那么神秘,说白了就是"教计算机按规矩办事"。
## 先建立三个最基础的概念
在看代码之前,我们先认识三个词,它们会反复出现:
1. 变量——就是一个"贴了标签的盒子"
Python
1
`x = 0`
这句话的意思是:拿一个盒子,贴上标签叫`x` ,在里面放进数字`0` 。以后写`x = x + 1` ,就是把盒子里的东西拿出来加 1,再放回去。
2. 列表——就是一排有编号的格子
Python
1
`route = [(0, 0)]`
`route` 是一个列表(用方括号`[]` 表示),可以理解成一排格子,每个格子能放一个东西。格子从 0 开始编号(注意不是从 1 开始,这是编程里最常见的"反直觉"设计)。
3. 循环——就是"重复做同一件事"
Python
1
`for ch in s:`
意思是:把`s` 里的东西 一个一个 拿出来,每次放到`ch` 里,然后执行缩进的那段代码。`s` 里有几个字母,这段代码就重复几次。
# 上午的程序:让一个小人在纸上走路
## 这个程序要解决什么问题?
想象有一个小人站在坐标纸的正中央,我们把这个位置记作`(0, 0)` 。然后我们给他一串口令:
- `F` = Forward,向前走一步(y 加 1)
- `B` = Backward,向后退一步(y 减 1)
- `L` = Left,向左走一步(x 减 1)
- `R` = Right,向右走一步(x 加 1)
比如输入`FRBL` ,小人走的路线是:前、右、后、左——咦,这不就是绕了一个方块,又回到原地了吗?程序的任务,就是把他走过的每一个位置都记下来,并告诉我们最后结果。
## 逐行讲解
Python
1
`# -*- coding: utf-8 -*-`
这一行以`#` 开头,叫 注释 。注释是写给人看的,计算机会完全忽略它。这句的意思是告诉 Python:"这个文件里有中文,请用 UTF-8 编码读取。"
Python
1
`s = input("请输入一串字母(只含F、B、L、R):")`
`input()` 是一个"暂停并等待"的指令:程序运行到这里会停下来,在屏幕上显示括号里的提示语,等你用键盘打字、按回车。你输入的内容(比如`FRBL` )会被装进`s` 这个盒子里。
小知识:`input()` 拿到的东西永远是 文字(字符串) ,哪怕你输入的是 123,它也认为是"一二三"这三个字符,而不是数字。
Python
1
`x, y = 0, 0`
这是同时给两个盒子赋值,等价于:
Python
1
2
`x = 0
y = 0`
小人的起点就是 (0, 0)。
Python
1
`route = [(0, 0)]`
这是整个程序里 最关键的一行之一 ,也是新手最容易忘的一步。
`(0, 0)` 这种用圆括号包起来的东西叫 元组 ,你现在可以简单理解成"一对坐标"。我们让`route` 列表一开始就装着起点——因为题目要求记录"起点 和 每一步结束后的位置",起点必须先放进去!
### 进入循环:一个口令一个动作
Python
1
`for ch in s:`
开始循环。假设你输入的是`FRBL` ,那么:
- 第 1 圈:`ch` 里装着`'F'`
- 第 2 圈:`ch` 里装着`'R'`
- 第 3 圈:`ch` 里装着`'B'`
- 第 4 圈:`ch` 里装着`'L'`
循环体里的代码都向右缩进了 4 个空格, 缩进代表"这些代码属于循环内部" ,Python 靠缩进判断代码的归属,所以缩进不能乱。
Python
1
2
3
4
5
6
7
8
` if ch == 'F':
y += 1
elif ch == 'B':
y -= 1
elif ch == 'L':
x -= 1
elif ch == 'R':
x += 1`
这是一串条件判断,注意两个细节:
- `==` 是两个等号,意思是"判断左右是否相等"。 一个等号是赋值,两个等号才是比较 ,这是新手最常写错的地方。
- `y += 1` 是`y = y + 1` 的简写,意思是"把 y 加 1"。类似地`-=` 就是减。
程序会从上往下依次问:这个字符是 F 吗?是就 y 加 1, 后面的判断全部跳过 ;不是就继续问是 B 吗……四个分支最多只有一个会执行。
Python
1
` route.append((x, y))`
每走完一步,就把当前坐标"追加"到`route` 列表的末尾。`append` (追加)就是在列表最后面加一个新格子。
我们可以看着`FRBL` 的执行过程:
时刻 x y route 列表 出发前 0 0 [(0,0)] F 之后 0 1 [(0,0), (0,1)] R 之后 1 1 [(0,0), (0,1), (1,1)] B 之后 1 0 [..., (1,0)] L 之后 0 0 [..., (1,0), (0,0)]
最后`route` 里有 5 个位置(1 个起点 + 4 步),但步数是 4 。这就是为什么下一行不用`route` 的长度算步数。
### 输出路线
Python
1
2
3
4
5
6
`print("路线:", end="")
for i, pos in enumerate(route):
if i > 0:
print(" → ", end="")
print(pos, end="")
print()`
`print()` 是"在屏幕上显示"。默认每打印一次就会换一行,但加上`end=""` 的意思是"这次打印完 不要换行 ",这样所有内容才能连在一行里。
这里出现了新工具`enumerate` :它能一边遍历列表,一边顺便告诉你"现在是第几个"。所以`i` 是编号(0、1、2……),`pos` 是坐标本身。
逻辑是:先打印"路线:",然后遍历每个位置——除了第 0 个(起点)之外,每个位置前面先打印一个箭头`→` ,再打印坐标。最终效果:
1
`路线:(0, 0) → (0, 1) → (1, 1) → (1, 0) → (0, 0)`
### 输出最终结果
Python
1
`print("最终坐标:", route[-1])`
`route[-1]` 是 Python 里一个很方便的写法: 负数编号表示"从后往前数" ,`-1` 就是最后一个格子,也就是最终位置。
Python
1
`print("总步数:", len(s))`
`len()` 用来量长度。`s` 是输入的字符串,`len(s)` 就是你输入了几个字母——正好等于步数(4)。注意不是`len(route)` ,因为路线包含起点,会多出 1。
Python
1
2
3
4
`if x == 0 and y == 0:
print("已回到起点")
else:
print("未回到起点")`
最后做判断:x 并且 y 都等于 0,才算回到起点。`and` 是"并且",两个条件必须同时成立。如果只有一个为 0,比如 (0, 1),那也不算。
这就是上午程序的全部内容。 它的套路可以总结成一句话:定好起点 → 一边走一边记 → 走完做汇报。
# 下午的程序:给机器人当"大脑"
## 这个程序要解决什么问题?
假设有一个机器人,它需要根据两个信息决定动作:
- 距离 :前方障碍物离它多远(厘米)
- 电量 :还剩多少电(百分比)
规矩是: 先看电量,再看距离 。电量不足 20%,不管前面多空旷都得去充电;电量够,才根据障碍物远近决定停车、减速还是正常开。
题目给了 6 组测试数据,注意它们是 6 种互不相干的情况 ,不是连续发生的——每一组都独立判断一次。
## 逐行讲解
Python
1
2
`distances = [80, 35, 10, 80, 20, 50]
batteries = [60, 60, 60, 15, 20, 20]`
这是两个列表。相同位置的数字配成一对:第 0 个 80 和第 0 个 60 是第一组(80 厘米、60% 电),以此类推。一共 6 组。
### 把判断逻辑封装成一个函数
Python
1
`def decide_action(distance, battery):`
`def` 是 define(定义)的缩写,用来定义一个 函数 。函数可以理解成"一台机器":你从这头塞进去原料(距离和电量),它从那头吐出产品(动作文字)。
括号里的`distance, battery` 叫 参数 ,是这台机器工作时需要的两份原料。把一段逻辑写成函数的好处是: 写一次,以后可以反复调用 ,而且主程序会显得很干净。
Python
1
2
3
4
5
6
7
8
` if battery < 20:
return "停止并充电"
elif distance < 20:
return "停止避障"
elif distance < 50:
return "减速前进"
else:
return "正常前进"`
函数体里是判断逻辑。`return` 的意思是"把结果递出去,函数到此结束"。
这里有一个 非常巧妙的顺序设计 ,新手值得仔细体会:
1. `battery < 20` 放在 第一位 。只要电量不足,立刻`return` ,后面的距离判断根本不会执行。这就保证了"电量优先"——第 4 组虽然距离 80 厘米很空旷,但电量只有 15%,照样去充电。
2. 走到`distance < 20` 这一行时,电量必然已经 ≥ 20 了(否则上一行就 return 了),所以不用重复写电量条件。
3. 走到`distance < 50` 时,距离必然已经 ≥ 20,所以这里天然表示"20 到 49 之间"。
这就是边界值的正确处理 :
- 电量正好 20:`< 20` 不成立 → 不算充电(题目说"20% 及以上"就达标)
- 距离正好 20:`< 20` 不成立、`< 50` 成立 → 减速前进
- 距离正好 50:`< 50` 不成立 → 落到 else,正常前进
三个边界值恰好都落在题目要求的档位上。
### 准备一个"记账本"
Python
1
`counts = {}`
花括号`{}` 表示 字典 。字典不是一排编号格子,而是一本"成对记账本":每个名字对应一个数字。我们准备用它记录每种动作出现了几次,比如最后会变成:
Python
1
`{"正常前进": 2, "减速前进": 2, "停止避障": 1, "停止并充电": 1}`
### 六组数据逐个判断
Python
1
`for i in range(len(distances)):`
`range(n)` 会生成 0 到 n-1 的一串数字。`len(distances)` 是 6,所以`i` 会依次取 0、1、2、3、4、5,正好循环 6 次。我们用`i` 当下标去两个列表里取同一组的数据。
Python
1
2
` d = distances[i]
b = batteries[i]`
把第`i` 组的距离取出来放进`d` ,电量放进`b` 。
Python
1
` action = decide_action(d, b)`
调用函数 :把`d` 和`b` 塞给前面造好的那台机器,机器吐出的动作文字装进`action` 。你看,主程序完全不用关心函数内部怎么判断的,这就是封装的好处。
Python
1
` print("第%d组:距离%d厘米,电量%d%% -> %s" % (i + 1, d, b, action))`
这一行看起来复杂,其实只是"按模板填空"。字符串里的占位符:
- `%d` 表示这里放一个整数
- `%s` 表示这里放一段文字
- `%%` 表示一个真正的百分号(因为单独的`%` 有特殊含义,要写两个)
为什么是`i + 1` 而不是`i` ?因为`i` 从 0 开始,但人习惯说"第 1 组",所以显示时加 1。 计算机内部从 0 数,给人看时从 1 数 ,这是常见的小处理。
Python
1
` counts[action] = counts.get(action, 0) + 1`
这是"记账"的一行,也是新手可能觉得绕的一行,拆开看:
- `counts.get(action, 0)` :查一下账本里这个动作出现过几次。如果是第一次出现(账本里还没这个名字),就当作 0。
- `+ 1` :把次数加 1。
- `counts[action] = ...` :再写回账本。
效果就是:每判断一组,对应动作的计数就加 1。 注意这行在循环内部 ,所以即使某组结果是"停止",计数和循环都会继续,下一组照常判断。
### 输出最终统计
Python
1
`order = ["正常前进", "减速前进", "停止避障", "停止并充电"]`
为什么要专门定义一个顺序?因为字典本身不保证排列顺序,如果直接打印`counts` ,四种动作的先后可能每次不同。我们规定一个固定顺序,输出更整齐,也能保证 四项全部出现 ,哪怕某项是 0 次。
Python
1
`print("统计结果:" + ",".join("%s%d次" % (n, counts.get(n, 0)) for n in order))`
这一行信息量大,拆开:
- `for n in order` :按规定顺序依次取出每个动作名
- `"%s%d次" % (n, counts.get(n, 0))` :拼成"正常前进2次"这样的片段
- `",".join(...)` :用逗号把所有片段连成一整句
- 最后和"统计结果:"拼在一起打印
输出:
1
`统计结果:正常前进2次,减速前进2次,停止避障1次,停止并充电1次`
四项加起来 2+2+1+1 = 6,正好等于数据组数,说明没有漏掉任何一组。
# 把两段程序放在一起对比
上午:走路 下午:机器人 数据从哪来 `input()` 键盘输入 直接写在程序里的两个列表 核心动作 循环里不断改变 x、y 循环里反复调用判断函数 怎么记结果 列表`append` 每个位置 字典给每种动作计数 判断关键 if/elif 识别是哪个字母 if/elif 注意先后顺序 ,电量优先 最后做什么 汇报路线、终点、是否回原点 汇报每组动作和总统计
你会发现两个程序的骨架其实是一样的:
1
2
3
4
5
`准备阶段(变量、列表)
↓
循环:每次取一份数据 → 判断 → 记录
↓
收尾:把记录的结果打印出来`
这个"准备 → 循环处理 → 汇报"的结构,是大量程序的通用模板,以后你会反复遇到。
DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。
更多推荐

所有评论(0)