Python基础讲义(十):组合类型综合
单元项目
0x01内容导图

0x02九宫算术
- 问题描述:将1-9填入3*3的矩阵,满足行、列、对角线和都相等,可扩展为n*n的矩阵(n为奇数)
- 由来:河图洛书中的洛书

-
《射雕英雄传》中黄蓉口诀:戴9履1,左3右7,2、4为肩,6、8为足,5坐中间
-
填数规则:
- 规则1:最大数位于中间行最后列
- 规则2:行+1,列+1,未填则填数
- 规则3:否则退回原处,列减1,填数

-
实现分析
- 搭建程序框架
- 初始化二维列表
- 填数
- 显示
- 初始化:列表推导式,深拷贝
- 搭建程序框架

- 显示:二维列表,多重循环
- 填数流程图

- 完整代码
def init():
n = int(input())
grid = [[0]*3 for j in range(n)]
return grid
def fill(grid):
n = len(grid)
r, c = n // 2, n - 1
for i in range(n*n, 0, -1):
grid[r][c] = i
r = (r + 1) % n
c = (c + 1) % n
if grid[r][c] != 0:
r, c = r - 1, c - 2
def disp(grid):
n = len(grid)
for i in range(n):
for j in range(n):
print("{:3}".format(grid[i][j]), end="")
print()
def run():
grid = init()
fill(grid)
disp(grid)
if __name__ == "__main__":
run()
0x03约瑟夫环
-
问题描述:n个小孩围成一圈,从第1个小孩开始报数,报到m的倍数离开,直到最后一个。求最后小孩的编号。
-
由来:据说著名犹太历史学家Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定了一个自杀方式,41个人排成一个圆圈,由第1个人开始报数,每报数到第3人该人就必须自杀,然后再由下一个重新报数,直到所有人都自杀身亡为止。
-
常见问题求解:
- 剩下n人的编号
- 求离队顺序
-
实现分析:
- 搭建运行框架
- 初始化列表
- 求解
- 获得获胜编号
- 初始化:列表推导式
- 获得获胜编号:列表推导式
- 求解:围成一圈、循环设计
- 搭建运行框架

- 完整代码
def init():
n, m = map(int, input().split())
kids = [i for i in range(1, n+1)]
return kids, m
def solve(kids, m):
n = r = len(kids)
count, index = 0, -1
while r > 1:
index = (index + 1) % n
if kids[index] == 0: continue
count += 1
if count == m:
kids[index] = 0
r -= 1
count = 0
return getwinner(kids)
def getwinner(kids):
ls = [i for i in kids if i != 0]
return ls[0]
def run():
kids, m = init()
winner = solve(kids, m)
print(winner)
if __name__ == "__main__":
run()
0x04单词统计
-
Google公司开发的流行分布式计算框架
-
map过程:建立映射
-
分组过程:按键进行分组
-
reduce过程:合并过程
-
过程分析
- 包含单词的文本或文件
- map:(hello, 1), (this, 1), (is 1), (a, 1), (pen 1), (this, 1), (is, 1), (world, 1), (hello, 1)...
- 分组:{hello:[1, 1], this:[1, 1], is: [1, 1], pen:[1]...
- reduce: (hello, 2), (this, 2), (is, 2), (pen, 1)...
- 代码实现
def split_words(text): #拆分单词,返回单词列表 import re p = re.compile(r"\b\w+\b") words = re.findall(p, text) return words def word_map(word): #为单词建立词频条目 return (word, 1) def partition(wordmap): #按键分组 dic = {} for item in wordmap: key, value = item[0], item[1] ls = dic.get(key, []) ls.append(value) dic[key] = ls return dic.items() def reduce_words(item): #合并,此处就是统计过程 return (item[0], sum(item[1])) def init_data(): s = "this is a pen.this is a dog.it is lovely." return split_words(s) def handle_data(data): m = [word_map(w) for w in data] #map items = partition(m) return [reduce_words(item) for item in items] #reduce def run(): data = init_data() result = handle_data(data) print(result) if __name__ == "__main__": run()案例扩展:
- 成绩统计,等级统计
- 倒排索引
0x05小结
- 熟悉组合类型的使用场合
- 熟练掌握组合类型常用操作并能灵活应用
- 理解MapReduce原理,理解函数抽象
浙公网安备 33010602011771号